void GenerateTerrain()
    {
        int halfHeight = mapSize.y / 2;

        for (int x = 0; x < mapSize.x; x++)
        {
            for (int y = 0; y < mapSize.y; y++)
            {
                float density = halfHeight - y;
                density += Noise.CalcPixel1DFractal(x, 0.03f, 3) * 30.0f;

                float noise = Noise.CalcPixel2DFractal(x, y, 0.01f, 3);

                if (density > 0)
                {
                    if (noise <= 0.3)
                    {
                        continue;
                    }

                    float randomLight = Noise.CalcPixel2D(x, y, 0.03f);
                    if (randomLight >= 0.91f)
                    {
                        float randomType = Noise.CalcPixel2D(x, y, 0.01f);
                        SetTile(new int2(x, y), tileInformations[(int)TileUtil.MinMaxNormalization(randomType, 0, 1, 3, 6)].id);
                    }
                    else
                    {
                        SetTile(new int2(x, y), tileInformations[1].id);
                    }
                }
            }
        }
    }
Esempio n. 2
0
        public void UpdateTexture(TileLight[] lights)
        {
            for (int x = 0; x < chunkSize.x; x++)
            {
                for (int y = 0; y < chunkSize.y; y++)
                {
                    int2 lightPosition = TileUtil.TileToWorldTile(new int2(x, y), chunkPosition, chunkSize);

                    int index = TileUtil.To1DIndex(lightPosition, mapSize);

                    int sunLight = lights[index].GetSunLight();

                    int torchRedLight   = lights[index].GetRedLight();
                    int torchGreenLight = lights[index].GetGreenLight();
                    int torchBlueLight  = lights[index].GetBlueLight();

                    byte redIntensity   = (byte)Mathf.Max(torchRedLight, sunLight);
                    byte greenIntensity = (byte)Mathf.Max(torchGreenLight, sunLight);
                    byte blueIntensity  = (byte)Mathf.Max(torchBlueLight, sunLight);

                    Color32 color = new Color32(redIntensity, greenIntensity, blueIntensity, 255);
                    texture.SetPixel(x, y, color);
                }
            }

            texture.Apply();
        }
        private static bool FindShape(PointD pt, List <EGIS.ShapeFileLib.ShapeFile> layers, int zoomLevel, ref int layerIndex, ref int recordIndex)
        {
            double zoom  = TileUtil.ZoomLevelToScale(zoomLevel);
            double delta = 8.0 / zoom;

            //PointD ptf = new PointD(pt.X, pt.Y);

            for (int l = layers.Count - 1; l >= 0; l--)
            {
                RectangleD extent = layers[l].Extent;
                extent.Inflate(delta, delta);
                if ((extent.Contains(pt) || layers[l].ShapeType == ShapeType.Point ||
                     layers[l].ShapeType == ShapeType.PointM || layers[l].ShapeType == ShapeType.PointZ) &&
                    layers[l].IsVisibleAtZoomLevel((float)zoom))
                {
                    int selectedIndex = layers[l].GetShapeIndexContainingPoint(pt, delta);
                    if (selectedIndex >= 0)
                    {
                        layerIndex  = l;
                        recordIndex = selectedIndex;
                        return(true);
                    }
                }
            }

            return(false);
        }
    public bool SetLight(int2 worldTilePosition, int value, LightType type)
    {
        if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize))
        {
            return(false);
        }

        int index = TileUtil.To1DIndex(worldTilePosition, mapSize);

        if (lights[index].GetLight(type) == value)
        {
            return(false);
        }

        int2 chunkPosition = TileUtil.WorldTileToChunk(worldTilePosition, chunkSize);

        if (chunks.TryGetValue(chunkPosition, out TileChunk chunk))
        {
            chunk.SetLightDirty();
        }
        else
        {
            TileChunk newChunk = GenerateChunk(chunkPosition);
            newChunk.SetLightDirty();
        }

        lights[index].SetLight(value, type);

        return(true);
    }
Esempio n. 5
0
        public void GenerateMap()
        {
            TileGenerator tileGenerator = new TileGenerator(WaterPrefab, GrassPrefab, DesertPrefab, MountainPrefab, ForestPrefab);

            Transform[,] tileTransforms = tileGenerator.GenerateTiles();
            tiles = new Tile[tileTransforms.GetLength(0), tileTransforms.GetLength(1)];

            // destroy/create container object
            Transform mapHolder = RestoreMapholder();

            // create the tiles
            for (int x = 0; x < Constants.MapSettings.MapSize.X; x++)
            {
                for (int y = 0; y < Constants.MapSettings.MapSize.Y; y++)
                {
                    Vector3   tilePosition = TileUtil.CoordToPosition(x, y);
                    Transform newTile      = Instantiate(tileTransforms[x, y], tilePosition, Quaternion.Euler(Vector3.right * 90)) as Transform;
                    newTile.localScale = Vector3.one * Constants.MapSettings.TileSize;
                    newTile.Rotate(Vector3.back * GenerateDegree());
                    newTile.parent = mapHolder;
                    newTile.name   = "X:" + x + " Y:" + y + " " + newTile.tag;

                    // store created tile for later access
                    tiles[x, y] = newTile.GetComponent <Tile>();

                    // set properties of tile
                    tiles[x, y].Type     = GetType(tileTransforms[x, y]);
                    tiles[x, y].Position = new Coord(x, y);
                }
            }
        }
    void OnDrawGizmos()
    {
        if (tiles == null)
        {
            return;
        }

        Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        int2 worldtilePosition = TileUtil.WorldToWorldtile(mousePosition);

        if (!TileUtil.BoundaryCheck(worldtilePosition, mapSize))
        {
            return;
        }

        int tileIndex = TileUtil.To1DIndex(worldtilePosition, mapSize);
        int tile      = tiles[tileIndex];

        if (tileInformations[tile].isSolid)
        {
            return;
        }

        Handles.Label(mousePosition, waterDensities[tileIndex].ToString());
    }
Esempio n. 7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="track"></param>
        /// <returns>the URI of the tile image</returns>
        protected async Task <Uri> SetImage(XmlDocument doc, MusicItem track)
        {
            var imageUri = await GetCoverUriOrDefault(track);

            TileUtil.SetImage(doc, imageUri);
            return(imageUri);
        }
Esempio n. 8
0
        public void TileToGeographic()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Server);
            IPoint p = TileUtil.TileToGeographic(1702, 3083, 13);

            Assert.AreApproximatelyEqual <double, double>(p.X, -105.20, 0.1);
            Assert.AreApproximatelyEqual <double, double>(p.Y, 40.61, 0.1);
        }
Esempio n. 9
0
        public override void BeforeSquareWideUpdate(XmlDocument doc, MusicItem track, Uri imageUri)
        {
            var largeXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare310x310ImageAndText02);

            TileUtil.SetImage(largeXml, imageUri);
            SetMeta(largeXml, track, includeAlbum: false);
            TileUtil.Embed(src: largeXml, dest: doc);
        }
Esempio n. 10
0
 public void SetUnit(MovableObject unit)
 {
     // actually set the position of the unit
     unit.transform.position = TileUtil.CoordToPosition(Position);
     // set a link to this tile in the unit
     unit.Tile = this;
     // store the building on this tile
     this.unit = unit;
 }
Esempio n. 11
0
 public void SetBuilding(SelectableObject building)
 {
     // actually set the position of the building
     building.transform.position = TileUtil.CoordToPosition(Position);
     // set a link to this tile in the building
     building.Tile = this;
     // store the building on this tile
     this.building = building;
 }
    public int GetTile(int2 worldTilePosition)
    {
        if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize))
        {
            return(-1);
        }

        return(tiles[TileUtil.To1DIndex(worldTilePosition, mapSize)]);
    }
    public int GetLight(int2 worldTilePosition, LightType type)
    {
        if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize))
        {
            return(0);
        }

        return(lights[TileUtil.To1DIndex(worldTilePosition, mapSize)].GetLight(type));
    }
Esempio n. 14
0
        public void Tile_0_0_0_Returns_Entire_World()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Server);

            IEnvelope e = TileUtil.GetEnvelopeFromZoomRowCol(0, 0, 0);

            Assert.AreEqual(e.XMax, 180);
            Assert.AreEqual(e.XMin, -180);
            Assert.AreApproximatelyEqual(e.YMax, 85.0511, 0.001);
            Assert.AreApproximatelyEqual(e.YMin, -85.0511, 0.001);
        }
Esempio n. 15
0
 protected void Update()
 {
     if (move)
     {
         Vector3 target = TileUtil.CoordToPosition(targetTile.Position);
         transform.position = Vector3.MoveTowards(transform.position, target, Time.deltaTime * Speed);
         if (Vector3.Distance(transform.position, target) < 0.001f)
         {
             move = false;
             Tile.RemoveUnit();
             targetTile.SetUnit(this);
         }
     }
 }
Esempio n. 16
0
        public void Tile_13_3083_1702()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Server);

            IPoint p1 = TileUtil.TileToGeographic(1702, 3083, 13);
            IPoint p2 = TileUtil.TileToGeographic(1703, 3084, 13);


            IEnvelope e = TileUtil.GetEnvelopeFromZoomRowCol(13, 1702, 3083);

            Assert.AreApproximatelyEqual(e.UpperLeft.X, p1.X, 0.001);
            Assert.AreApproximatelyEqual(e.LowerRight.X, p2.X, 0.001);
            Assert.AreApproximatelyEqual(e.UpperLeft.Y, p1.Y, 0.001);
            Assert.AreApproximatelyEqual(e.LowerRight.Y, p2.Y, 0.001);
        }
Esempio n. 17
0
        public void Init(int2 position, TileManager manager, int2 chunkSize, int2 mapSize, Material tileMaterial, Material lightMaterial)
        {
            tileManager   = manager;
            chunkPosition = position;
            mesh.Init(chunkSize, mapSize, chunkPosition, tileMaterial);
            lightTexture.Init(chunkSize, mapSize, chunkPosition, lightMaterial);

            int2    lightTextureTilePosition = TileUtil.TileToWorldTile(int2.zero, chunkPosition, chunkSize);
            Vector3 lightTexturePosition     = new Vector3(lightTextureTilePosition.x, lightTextureTilePosition.y);

            lightTexturePosition.z         -= 10;
            lightTexture.transform.position = lightTexturePosition;

            meshDirty  = true;
            lightDirty = true;
        }
Esempio n. 18
0
        private void OneTurn()
        {
            (int row, int col)pos1, pos2;
            Tile[] situation = new Tile[TileUtil.NUM_NEIGHBORS];

            RobbyWorld world = new RobbyWorld(10, 10, 0.5f);

            IList <Reaction> rules = world.GenerateRandomRules();

            StringBuilder sb = new StringBuilder();

            int ruleIndex;

            pos1 = world.RobbyPos;
            world.GetSituationAt(pos1, situation);
            ruleIndex = TileUtil.ToDecimal(situation);

            sb.AppendFormat(
                "Robby's position: ({0},{1})\n", pos1.row, pos1.col);
            sb.AppendFormat(
                "Robby's situation: {0} [ {1} ]\n",
                ruleIndex, TileUtil.ToString(situation));
            sb.AppendFormat(
                "Robby's action to take for situation {0}: {1}\n",
                ruleIndex, rules[ruleIndex]);
            sb.AppendFormat("Robby's original score: {0}", world.Score);

            sb.AppendLine("\nActing up...");
            world.NextTurn(rules);

            pos2 = world.RobbyPos;

            sb.AppendFormat(
                "Robby's new position: ({0},{1})\n", pos2.row, pos2.col);
            sb.AppendFormat(
                "Situation in original position: {0}\n",
                world[pos1.row, pos1.col]);
            sb.AppendFormat("Robby's new score: {0}", world.Score);

            Debug.Log(sb.ToString());
        }
    void Update()
    {
        currentFlowSpeed = Mathf.Clamp01(flowSpeed * Time.deltaTime);

        if (fluidUpdator == null)
        {
            fluidUpdator = StartCoroutine(nameof(UpdateFluid));
        }
        SunLightPropagation();
        TorchLightPropagation(ref torchRedLightPropagationQueue, ref torchRedLightRemovalQueue, LightType.R);
        TorchLightPropagation(ref torchGreenLightPropagationQueue, ref torchGreenLightRemovalQueue, LightType.G);
        TorchLightPropagation(ref torchBlueLightPropagationQueue, ref torchBlueLightRemovalQueue, LightType.B);
        UpdateChunks();

        Vector3 mousePosition     = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        int2    worldTilePosition = TileUtil.WorldToWorldtile(mousePosition);

        if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize))
        {
            return;
        }

        if (Input.GetMouseButton(0))
        {
            SetTile(worldTilePosition, tileInformations[1].id);
        }
        else if (Input.GetMouseButton(1))
        {
            SetTile(worldTilePosition, tileInformations[0].id);
            fluidQueue.Enqueue(new Tuple <int, float>(TileUtil.To1DIndex(worldTilePosition, mapSize), 0.0f));
        }
        else if (Input.GetKeyDown(KeyCode.T))
        {
            SetTile(worldTilePosition, tileInformations[3].id);
        }
        else if (Input.GetKey(KeyCode.W))
        {
            SetTile(worldTilePosition, tileInformations[2].id);
            fluidQueue.Enqueue(new Tuple <int, float>(TileUtil.To1DIndex(worldTilePosition, mapSize), waterDensities[TileUtil.To1DIndex(worldTilePosition, mapSize)] + 3.0f));
        }
    }
    public bool SetTile(int2 worldTilePosition, int id)
    {
        if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize))
        {
            return(false);
        }

        int index = TileUtil.To1DIndex(worldTilePosition, mapSize);

        if (tiles[index] == id)
        {
            return(false);
        }

        int2 chunkPosition = TileUtil.WorldTileToChunk(worldTilePosition, chunkSize);

        if (chunks.TryGetValue(chunkPosition, out TileChunk chunk))
        {
            chunk.SetMeshDirty();
        }
        else
        {
            TileChunk newChunk = GenerateChunk(chunkPosition);
            newChunk.SetMeshDirty();
        }

        if (tileInformations[id].isSolid)
        {
            fluidQueue.Enqueue(new Tuple <int, float>(index, 0.0f));
        }

        LightEmission beforeEmission = tileInformations[tiles[index]].emission;

        tiles[index] = id;

        SetEmission(worldTilePosition, tileInformations[id].emission);
        CheckTileToUpdateLight(worldTilePosition, id, beforeEmission);

        return(true);
    }
Esempio n. 21
0
        /// <summary>
        /// Cover to the left, title, album, artist to the right.
        /// </summary>
        /// <param name="track"></param>
        /// <returns></returns>
        public override async Task Update(MusicItem track)
        {
            // wide
            var wideXml  = TileUpdateManager.GetTemplateContent(wideImageText02);
            var imageUri = await SetImageAndMeta(wideXml, track);

            // square
            var squareXml = TileUpdateManager.GetTemplateContent(squareText03);

            SetMeta(squareXml, track);

            TileUtil.Embed(squareXml, wideXml);

            BeforeSquareWideUpdate(wideXml, track, imageUri);

            var trackDuration        = track.Duration;
            var trackDurationSeconds = trackDuration.TotalSeconds;
            var isTrackDurationValid = trackDurationSeconds > 0 && trackDurationSeconds < 10000;
            var expiration           = isTrackDurationValid ? trackDuration : TimeSpan.FromMinutes(5);

            TileUtil.Update(wideXml, expiration);
        }
        void GenerateMesh(int[] tiles, float[] waterDensities)
        {
            vertices.Clear();
            indices.Clear();
            uvs.Clear();
            colors.Clear();
            paths.Clear();;
            visited.Clear();

            int numQuads = 0;

            for (int x = 0; x < chunkSize.x; x++)
            {
                for (int y = 0; y < chunkSize.y;)
                {
                    int2 tilePosition = TileUtil.TileToWorldTile(new int2(x, y), chunkPosition, chunkSize);
                    int  index        = TileUtil.To1DIndex(tilePosition, mapSize);
                    int  tile         = tiles[index];

                    if (tile == 0)
                    {
                        y++;
                        continue;
                    }

                    if (visited.Contains(tilePosition))
                    {
                        y++;
                        continue;
                    }

                    visited.Add(tilePosition);

                    int height;
                    for (height = 1; height + y < chunkSize.y; height++)
                    {
                        int2 nextPosition = tilePosition + TileUtil.Up * height;

                        if (!TileUtil.BoundaryCheck(nextPosition, chunkPosition, chunkSize))
                        {
                            break;
                        }

                        int nextIndex = TileUtil.To1DIndex(nextPosition, mapSize);

                        int nextTile = tiles[nextIndex];

                        if (nextTile != tile)
                        {
                            break;
                        }

                        if (!TileManager.tileInformations[tile].isSolid)
                        {
                            break;
                        }

                        if (visited.Contains(nextPosition))
                        {
                            break;
                        }

                        visited.Add(nextPosition);
                    }

                    bool done = false;
                    int  width;
                    for (width = 1; width + x < chunkSize.x; width++)
                    {
                        for (int dy = 0; dy < height; dy++)
                        {
                            int2 nextPosition = tilePosition + TileUtil.Up * dy + TileUtil.Right * width;

                            if (!TileUtil.BoundaryCheck(nextPosition, chunkPosition, chunkSize))
                            {
                                done = true;
                                break;
                            }

                            int nextIndex = TileUtil.To1DIndex(nextPosition, mapSize);

                            int nextTile = tiles[nextIndex];

                            if (nextTile != tile || visited.Contains(nextPosition))
                            {
                                done = true;
                                break;
                            }

                            if (!TileManager.tileInformations[tile].isSolid)
                            {
                                done = true;
                                break;
                            }
                        }

                        if (done)
                        {
                            break;
                        }

                        for (int dy = 0; dy < height; dy++)
                        {
                            int2 nextPosition =
                                tilePosition +
                                TileUtil.Up * dy +
                                TileUtil.Right * width;
                            visited.Add(nextPosition);
                        }
                    }

                    float2 scale = new float2(width, height);

                    List <Vector2> points = new List <Vector2>();
                    for (int i = 0; i < 4; i++)
                    {
                        Vector2 vertex = tileVertices[i] * scale + tilePosition;
                        vertices.Add(vertex);

                        Vector2 uv2 = tileVertices[i] * scale;
                        Vector4 uv4 = new Vector4(uv2.x, uv2.y, scale.x, scale.y);
                        uvs.Add(uv4);

                        Color32 color = TileManager.tileInformations[tile].color;
                        if (TileManager.tileInformations[tile].isSolid)
                        {
                            colors.Add(color);
                        }
                        else
                        {
                            float density = Mathf.Clamp(waterDensities[index], 0.0f, 1.0f);

                            int2 upPosition = tilePosition + TileUtil.Up;
                            if (TileUtil.BoundaryCheck(upPosition, mapSize))
                            {
                                int upTile = tiles[TileUtil.To1DIndex(upPosition, mapSize)];
                                if (!TileManager.tileInformations[upTile].isSolid && upTile != 0)
                                {
                                    density = 1.0f;
                                }
                            }

                            int2 downPosition = tilePosition + TileUtil.Down;
                            if (TileUtil.BoundaryCheck(downPosition, mapSize))
                            {
                                int downTile = tiles[TileUtil.To1DIndex(downPosition, mapSize)];
                                if (!TileManager.tileInformations[downTile].isSolid && downTile == 0)
                                {
                                    density = 1.0f;
                                }
                            }

                            color.a = (byte)(byte.MaxValue * density);
                            colors.Add(color);
                        }


                        // Not Optimized Collider Generation
                        Vector2 point = colliderPoints[i] * scale + tilePosition;
                        points.Add(point);
                    }
                    paths.Add(points);

                    for (int i = 0; i < 6; i++)
                    {
                        indices.Add(tileIndices[i] + numQuads * 4);
                    }

                    y += height;
                    numQuads++;
                }
            }
        }
Esempio n. 23
0
        private VectorTileLayer ProcessPolygonTile(ISpatialDataSource spatialLayer, int tileX, int tileY, int zoom)
        {
            int        tileSize   = TileSize;
            RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize);

            //create a buffer around the tileBounds
            tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05);

            int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold));

            System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize));

            using (IEnumerator <ISpatialData> data = spatialLayer.GetData(new BoundingBox()
            {
                MinX = tileBounds.Left,
                MinY = tileBounds.Top,
                MaxX = tileBounds.Right,
                MaxY = tileBounds.Bottom
            }))
            {
                GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
                {
                    XMin = -20,
                    YMin = -20,
                    XMax = tileSize + 20,
                    YMax = tileSize + 20
                };

                System.Drawing.Point[] pixelPoints           = new System.Drawing.Point[1024];
                System.Drawing.Point[] simplifiedPixelPoints = new System.Drawing.Point[1024];
                PointD[] pointsBuffer = new PointD[1024];

                List <System.Drawing.Point> clippedPolygon = new List <System.Drawing.Point>();

                VectorTileLayer tileLayer = new VectorTileLayer();
                tileLayer.Extent  = (uint)tileSize;
                tileLayer.Version = 2;
                tileLayer.Name    = spatialLayer.Name;

                while (data.MoveNext())
                {
                    ISpatialData spatialData = data.Current;

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id           = spatialData.Id,
                        Geometry     = new List <List <Coordinate> >(),
                        Attributes   = new List <AttributeKeyValue>(),
                        GeometryType = Tile.GeomType.Polygon
                    };

                    //get the point data
                    var recordPoints = spatialData.Geometry;
                    int partIndex    = 0;
                    foreach (PointD[] points in recordPoints)
                    {
                        //convert to pixel coordinates;
                        if (pixelPoints.Length < points.Length)
                        {
                            pixelPoints           = new System.Drawing.Point[points.Length + 10];
                            simplifiedPixelPoints = new System.Drawing.Point[points.Length + 10];
                        }

                        for (int n = 0; n < points.Length; ++n)
                        {
                            Int64 x, y;
                            TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize);
                            pixelPoints[n].X = (int)(x - tilePixelOffset.X);
                            pixelPoints[n].Y = (int)(y - tilePixelOffset.Y);
                        }

                        int outputCount = 0;
                        SimplifyPointData(pixelPoints, null, points.Length, simplificationFactor, simplifiedPixelPoints, null, ref pointsBuffer, ref outputCount);

                        if (outputCount > 1)
                        {
                            GeometryAlgorithms.PolygonClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPolygon);

                            if (clippedPolygon.Count > 0)
                            {
                                //output the clipped polygon
                                List <Coordinate> lineString = new List <Coordinate>();
                                feature.Geometry.Add(lineString);
                                for (int i = clippedPolygon.Count - 1; i >= 0; --i)
                                {
                                    lineString.Add(new Coordinate(clippedPolygon[i].X, clippedPolygon[i].Y));
                                }
                            }
                        }
                        ++partIndex;
                    }

                    //add the record attributes
                    foreach (var keyValue in spatialData.Attributes)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(keyValue.Key, keyValue.Value));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
                return(tileLayer);
            }
        }
Esempio n. 24
0
        private VectorTileLayer ProcessPointTile(ShapeFile shapeFile, int tileX, int tileY, int zoom, OutputTileFeatureDelegate outputTileFeature)
        {
            int        tileSize   = TileSize;
            RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize);

            //create a buffer around the tileBounds
            tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05);

            int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold));

            System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize));

            List <int> indicies = new List <int>();

            shapeFile.GetShapeIndiciesIntersectingRect(indicies, tileBounds);
            GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
            {
                XMin = -20,
                YMin = -20,
                XMax = tileSize + 20,
                YMax = tileSize + 20
            };


            VectorTileLayer tileLayer = new VectorTileLayer();

            tileLayer.Extent  = (uint)tileSize;
            tileLayer.Version = 2;
            tileLayer.Name    = !string.IsNullOrEmpty(shapeFile.Name) ? shapeFile.Name : System.IO.Path.GetFileNameWithoutExtension(shapeFile.FilePath);

            if (indicies.Count > 0)
            {
                foreach (int index in indicies)
                {
                    if (outputTileFeature != null && !outputTileFeature(shapeFile, index, zoom, tileX, tileY))
                    {
                        continue;
                    }

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id           = index.ToString(System.Globalization.CultureInfo.InvariantCulture),
                        Geometry     = new List <List <Coordinate> >(),
                        Attributes   = new List <AttributeKeyValue>(),
                        GeometryType = Tile.GeomType.Point
                    };

                    //output the pixel coordinates
                    List <Coordinate> coordinates = new List <Coordinate>();
                    //get the point data
                    var recordPoints = shapeFile.GetShapeDataD(index);
                    foreach (PointD[] points in recordPoints)
                    {
                        for (int n = 0; n < points.Length; ++n)
                        {
                            Int64 x, y;
                            TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize);
                            coordinates.Add(new Coordinate((int)(x - tilePixelOffset.X), (int)(y - tilePixelOffset.Y)));
                        }
                    }
                    if (coordinates.Count > 0)
                    {
                        feature.Geometry.Add(coordinates);
                    }

                    //add the record attributes
                    string[] fieldNames = shapeFile.GetAttributeFieldNames();
                    string[] values     = shapeFile.GetAttributeFieldValues(index);
                    for (int n = 0; n < values.Length; ++n)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(fieldNames[n], values[n].Trim()));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
            }

            return(tileLayer);
        }
Esempio n. 25
0
        private VectorTileLayer ProcessPointTile(ISpatialDataSource spatialLayer, int tileX, int tileY, int zoom)
        {
            int        tileSize   = TileSize;
            RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize);

            //create a buffer around the tileBounds
            tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05);

            int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold));

            System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize));

            using (IEnumerator <ISpatialData> data = spatialLayer.GetData(new BoundingBox()
            {
                MinX = tileBounds.Left,
                MinY = tileBounds.Top,
                MaxX = tileBounds.Right,
                MaxY = tileBounds.Bottom
            }))
            {
                GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
                {
                    XMin = -20,
                    YMin = -20,
                    XMax = tileSize + 20,
                    YMax = tileSize + 20
                };


                VectorTileLayer tileLayer = new VectorTileLayer();
                tileLayer.Extent  = (uint)tileSize;
                tileLayer.Version = 2;
                tileLayer.Name    = spatialLayer.Name;

                while (data.MoveNext())
                {
                    ISpatialData      spatialData = data.Current;
                    VectorTileFeature feature     = new VectorTileFeature()
                    {
                        Id           = spatialData.Id,
                        Geometry     = new List <List <Coordinate> >(),
                        Attributes   = new List <AttributeKeyValue>(),
                        GeometryType = Tile.GeomType.Point
                    };

                    //output the pixel coordinates
                    List <Coordinate> coordinates = new List <Coordinate>();
                    var recordPoints = spatialData.Geometry;
                    foreach (PointD[] points in recordPoints)
                    {
                        for (int n = 0; n < points.Length; ++n)
                        {
                            Int64 x, y;
                            TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize);
                            coordinates.Add(new Coordinate((int)(x - tilePixelOffset.X), (int)(y - tilePixelOffset.Y)));
                        }
                    }
                    if (coordinates.Count > 0)
                    {
                        feature.Geometry.Add(coordinates);
                    }

                    //add the record attributes
                    foreach (var keyValue in spatialData.Attributes)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(keyValue.Key, keyValue.Value));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
                return(tileLayer);
            }
        }
Esempio n. 26
0
        private VectorTileLayer ProcessPolygonTile(ShapeFile shapeFile, int tileX, int tileY, int zoom, OutputTileFeatureDelegate outputTileFeature)
        {
            int        tileSize   = TileSize;
            RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize);

            //create a buffer around the tileBounds
            tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05);

            int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold));

            System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize));

            List <int> indicies = new List <int>();

            shapeFile.GetShapeIndiciesIntersectingRect(indicies, tileBounds);
            GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
            {
                XMin = -20,
                YMin = -20,
                XMax = tileSize + 20,
                YMax = tileSize + 20
            };

            List <System.Drawing.Point> clippedPolygon = new List <System.Drawing.Point>();


            VectorTileLayer tileLayer = new VectorTileLayer();

            tileLayer.Extent  = (uint)tileSize;
            tileLayer.Version = 2;
            tileLayer.Name    = !string.IsNullOrEmpty(shapeFile.Name) ? shapeFile.Name : System.IO.Path.GetFileNameWithoutExtension(shapeFile.FilePath);

            if (indicies.Count > 0)
            {
                foreach (int index in indicies)
                {
                    if (outputTileFeature != null && !outputTileFeature(shapeFile, index, zoom, tileX, tileY))
                    {
                        continue;
                    }

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id           = index.ToString(System.Globalization.CultureInfo.InvariantCulture),
                        Geometry     = new List <List <Coordinate> >(),
                        Attributes   = new List <AttributeKeyValue>(),
                        GeometryType = Tile.GeomType.Polygon
                    };

                    //get the point data
                    var recordPoints = shapeFile.GetShapeDataD(index);
                    int partIndex    = 0;
                    foreach (PointD[] points in recordPoints)
                    {
                        //convert to pixel coordinates;
                        if (pixelPoints.Length < points.Length)
                        {
                            pixelPoints           = new System.Drawing.Point[points.Length + 10];
                            simplifiedPixelPoints = new System.Drawing.Point[points.Length + 10];
                        }
                        int pointCount = 0;
                        for (int n = 0; n < points.Length; ++n)
                        {
                            Int64 x, y;
                            TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize);

                            pixelPoints[pointCount].X   = (int)(x - tilePixelOffset.X);
                            pixelPoints[pointCount++].Y = (int)(y - tilePixelOffset.Y);
                        }
                        ////check for duplicates points at end after they have been converted to pixel coordinates
                        ////polygons need at least 3 points so don't reduce less than this
                        //while(pointCount > 3 && (pixelPoints[pointCount-1] == pixelPoints[pointCount - 2]))
                        //{
                        //    --pointCount;
                        //}

                        int outputCount = 0;
                        SimplifyPointData(pixelPoints, null, pointCount, simplificationFactor, simplifiedPixelPoints, null, ref pointsBuffer, ref outputCount);
                        //simplifiedPixelPoints[outputCount++] = pixelPoints[pointCount-1];

                        if (outputCount > 1)
                        {
                            GeometryAlgorithms.PolygonClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPolygon);

                            if (clippedPolygon.Count > 0)
                            {
                                //output the clipped polygon
                                List <Coordinate> lineString = new List <Coordinate>();
                                feature.Geometry.Add(lineString);
                                for (int i = clippedPolygon.Count - 1; i >= 0; --i)
                                {
                                    lineString.Add(new Coordinate(clippedPolygon[i].X, clippedPolygon[i].Y));
                                }
                            }
                        }
                        ++partIndex;
                    }

                    //add the record attributes
                    string[] fieldNames = shapeFile.GetAttributeFieldNames();
                    string[] values     = shapeFile.GetAttributeFieldValues(index);
                    for (int n = 0; n < values.Length; ++n)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(fieldNames[n], values[n].Trim()));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
            }

            return(tileLayer);
        }
Esempio n. 27
0
        private VectorTileLayer ProcessLineStringTile(ShapeFile shapeFile, int tileX, int tileY, int zoom, OutputTileFeatureDelegate outputTileFeature)
        {
            int        tileSize   = TileSize;
            RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize);

            //create a buffer around the tileBounds
            tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05);

            int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold));

            System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize));

            List <int> indicies = new List <int>();

            shapeFile.GetShapeIndiciesIntersectingRect(indicies, tileBounds);
            GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
            {
                XMin = -20,
                YMin = -20,
                XMax = tileSize + 20,
                YMax = tileSize + 20
            };
            bool outputMeasureValues = this.OutputMeasureValues && (shapeFile.ShapeType == ShapeType.PolyLineM || shapeFile.ShapeType == ShapeType.PolyLineZ);

            System.Drawing.Point[] pixelPoints           = new System.Drawing.Point[1024];
            System.Drawing.Point[] simplifiedPixelPoints = new System.Drawing.Point[1024];
            double[] simplifiedMeasures = new double[1024];

            PointD[] pointsBuffer = new PointD[1024];

            VectorTileLayer tileLayer = new VectorTileLayer();

            tileLayer.Extent  = (uint)tileSize;
            tileLayer.Version = 2;
            tileLayer.Name    = !string.IsNullOrEmpty(shapeFile.Name) ? shapeFile.Name : System.IO.Path.GetFileNameWithoutExtension(shapeFile.FilePath);

            if (indicies.Count > 0)
            {
                foreach (int index in indicies)
                {
                    if (outputTileFeature != null && !outputTileFeature(shapeFile, index, zoom, tileX, tileY))
                    {
                        continue;
                    }

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id         = index.ToString(System.Globalization.CultureInfo.InvariantCulture),
                        Geometry   = new List <List <Coordinate> >(),
                        Attributes = new List <AttributeKeyValue>()
                    };

                    //get the point data
                    var recordPoints = shapeFile.GetShapeDataD(index);
                    System.Collections.ObjectModel.ReadOnlyCollection <double[]> recordMeasures = null;

                    if (outputMeasureValues)
                    {
                        recordMeasures = shapeFile.GetShapeMDataD(index);
                    }

                    List <double> outputMeasures = new List <double>();
                    int           partIndex      = 0;
                    foreach (PointD[] points in recordPoints)
                    {
                        double[] measures = recordMeasures != null ? recordMeasures[partIndex] : null;
                        //convert to pixel coordinates;
                        if (pixelPoints.Length < points.Length)
                        {
                            pixelPoints           = new System.Drawing.Point[points.Length + 10];
                            simplifiedPixelPoints = new System.Drawing.Point[points.Length + 10];
                            simplifiedMeasures    = new double[points.Length + 10];
                        }

                        for (int n = 0; n < points.Length; ++n)
                        {
                            Int64 x, y;
                            TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize);
                            pixelPoints[n].X = (int)(x - tilePixelOffset.X);
                            pixelPoints[n].Y = (int)(y - tilePixelOffset.Y);
                        }

                        int outputCount = 0;
                        SimplifyPointData(pixelPoints, measures, points.Length, simplificationFactor, simplifiedPixelPoints, simplifiedMeasures, ref pointsBuffer, ref outputCount);

                        //output count may be zero for short records at low zoom levels as
                        //the pixel coordinates wil be a single point after simplification
                        if (outputCount > 0)
                        {
                            List <int> clippedPoints = new List <int>();
                            List <int> parts         = new List <int>();

                            if (outputMeasureValues)
                            {
                                List <double> clippedMeasures = new List <double>();
                                GeometryAlgorithms.PolyLineClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPoints, parts, simplifiedMeasures, clippedMeasures);
                                outputMeasures.AddRange(clippedMeasures);
                            }
                            else
                            {
                                GeometryAlgorithms.PolyLineClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPoints, parts);
                            }
                            if (parts.Count > 0)
                            {
                                //output the clipped polyline
                                for (int n = 0; n < parts.Count; ++n)
                                {
                                    int index1 = parts[n];
                                    int index2 = n < parts.Count - 1 ? parts[n + 1] : clippedPoints.Count;

                                    List <Coordinate> lineString = new List <Coordinate>();
                                    feature.GeometryType = Tile.GeomType.LineString;
                                    feature.Geometry.Add(lineString);
                                    //clipped points store separate x/y pairs so there will be two values per measure
                                    for (int i = index1; i < index2; i += 2)
                                    {
                                        lineString.Add(new Coordinate(clippedPoints[i], clippedPoints[i + 1]));
                                    }
                                }
                            }
                        }
                        ++partIndex;
                    }

                    //add the record attributes
                    string[] fieldNames = shapeFile.GetAttributeFieldNames();
                    string[] values     = shapeFile.GetAttributeFieldValues(index);
                    for (int n = 0; n < values.Length; ++n)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(fieldNames[n], values[n].Trim()));
                    }
                    if (outputMeasureValues)
                    {
                        string s = Newtonsoft.Json.JsonConvert.SerializeObject(outputMeasures, new DoubleFormatConverter(4));
                        feature.Attributes.Add(new AttributeKeyValue(this.MeasuresAttributeName, s));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
            }
            return(tileLayer);
        }
Esempio n. 28
0
        private static string LocateShape(PointD pt, List <EGIS.ShapeFileLib.ShapeFile> layers, int zoomLevel, List <SessionCustomRenderSettingsEntry> customRenderSettingsList, ref int layerIndex, ref int recordIndex)
        {
            //changed V3.3 - coords now sent in lat/long
            //convert pt to lat long from merc
            //pt = ShapeFile.MercatorToLL(pt);
            //System.Diagnostics.Debug.WriteLine(pt);
            double zoom  = TileUtil.ZoomLevelToScale(zoomLevel);
            double delta = 8.0 / zoom;
            PointD ptf   = new PointD(pt.X, pt.Y);
            //save the existing ICustomRenderSettings and set the dynamicCustomRenderSettings
            List <SessionCustomRenderSettingsEntry> defaultcustomRenderSettingsList = new List <SessionCustomRenderSettingsEntry>();

            if (customRenderSettingsList != null)
            {
                for (int n = 0; n < customRenderSettingsList.Count; n++)
                {
                    int index = customRenderSettingsList[n].LayerIndex;
                    if (index < layers.Count)
                    {
                        defaultcustomRenderSettingsList.Add(new SessionCustomRenderSettingsEntry(layerIndex, layers[layerIndex].RenderSettings.CustomRenderSettings));
                        layers[layerIndex].RenderSettings.CustomRenderSettings = customRenderSettingsList[n].CustomRenderSettings;
                    }
                }
            }

            try
            {
                for (int l = layers.Count - 1; l >= 0; l--)
                {
                    bool useToolTip       = (layers[l].RenderSettings != null && layers[l].RenderSettings.UseToolTip);
                    bool useCustomToolTip = (useToolTip && layers[l].RenderSettings.CustomRenderSettings != null && layers[l].RenderSettings.CustomRenderSettings.UseCustomTooltips);
                    if (layers[l].Extent.Contains(ptf) && layers[l].IsVisibleAtZoomLevel((float)zoom) && useToolTip)
                    {
                        int selectedIndex = layers[l].GetShapeIndexContainingPoint(ptf, delta);
                        if (selectedIndex >= 0)
                        {
                            layerIndex  = l;
                            recordIndex = selectedIndex;
                            if (useCustomToolTip)
                            {
                                return(layers[l].RenderSettings.CustomRenderSettings.GetRecordToolTip(selectedIndex));
                            }
                            else
                            {
                                string s = "record : " + selectedIndex.ToString(System.Globalization.CultureInfo.InvariantCulture);
                                if (layers[l].RenderSettings.ToolTipFieldIndex >= 0)
                                {
                                    string temp = layers[l].RenderSettings.DbfReader.GetField(selectedIndex, layers[l].RenderSettings.ToolTipFieldIndex).Trim();
                                    if (temp.Length > 0)
                                    {
                                        s += "<br/>" + temp;
                                    }
                                }
                                return(s);
                            }
                        }
                    }
                }
            }
            finally
            {
                //restore any existing ICustomRenderSettings
                if (customRenderSettingsList != null)
                {
                    for (int n = 0; n < defaultcustomRenderSettingsList.Count; n++)
                    {
                        layers[defaultcustomRenderSettingsList[n].LayerIndex].RenderSettings.CustomRenderSettings = defaultcustomRenderSettingsList[n].CustomRenderSettings;
                    }
                }
            }
            return(null);
        }
Esempio n. 29
0
        private void ProcessRequestCore(HttpContext context)
        {
            DateTime dts = DateTime.Now;

            if (context.Request.Params["getshape"] != null)
            {
                ProcessGetShapeRequest(context);
                return;
            }
            int    w = 256 * 3;
            int    h = 256 * 3;
            int    tileX = 0, tileY = 0, zoomLevel = 0;
            PointD centerPoint = PointD.Empty;
            double zoom        = -1;

            int renderSettingsType = 0;

            int.TryParse(context.Request["rendertype"], out renderSettingsType);

            bool foundCompulsoryParameters = false;

            if (int.TryParse(context.Request["tx"], out tileX))
            {
                if (int.TryParse(context.Request["ty"], out tileY))
                {
                    if (int.TryParse(context.Request["zoom"], out zoomLevel))
                    {
                        centerPoint = TileUtil.GetMercatorCenterPointFromTile(tileX, tileY, zoomLevel);
                        zoom        = TileUtil.ZoomLevelToScale(zoomLevel);
                        foundCompulsoryParameters = true;
                    }
                }
            }

            if (!foundCompulsoryParameters)
            {
                throw new InvalidOperationException("compulsory parameters 'tx','ty' or 'zoom' missing");
            }


            string cachePath = "";
            bool   useCache  = CacheOnServer;

            if (useCache)
            {
                cachePath = CreateCachePath(context, tileX, tileY, zoomLevel);
            }

            if (string.IsNullOrEmpty(cachePath))
            {
                useCache = false;
            }

            context.Response.ContentType = "image/x-png";
            //is the image cached on the server?
            if (useCache && System.IO.File.Exists(cachePath))
            {
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
                context.Response.Cache.SetExpires(DateTime.Now.AddDays(7));
                context.Response.WriteFile(cachePath);
                context.Response.Flush();
                return;
            }

            //render the tile
            List <ShapeFile> mapLayers = CreateMapLayers(context);

            if (mapLayers == null)
            {
                throw new InvalidOperationException("No Map Layers");
            }
            //check if any layers are Point layers
            bool containsPointLayer = false;

            for (int n = mapLayers.Count - 1; n >= 0; --n)
            {
                if (mapLayers[n].ShapeType == ShapeType.Point || mapLayers[n].ShapeType == ShapeType.PointM || mapLayers[n].ShapeType == ShapeType.PointZ)
                {
                    containsPointLayer = true;
                }
            }
            if (containsPointLayer)
            {
                //draw to an image w x h so that labels overlapping tiles are rendered
                Bitmap bm  = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
                Bitmap bm2 = new Bitmap(w, h, PixelFormat.Format24bppRgb);
                try
                {
                    Graphics g  = Graphics.FromImage(bm);
                    Graphics g2 = Graphics.FromImage(bm2);
                    try
                    {
                        g2.Clear(MapBackgroundColor);
                        RenderMap(g2, mapLayers, w, h, centerPoint, zoom);
                        g.DrawImage(bm2, Rectangle.FromLTRB(0, 0, 256, 256), Rectangle.FromLTRB(256, 256, 512, 512), GraphicsUnit.Pixel);

                        //perform custom painting
                    }
                    finally
                    {
                        g.Dispose();
                        g2.Dispose();
                    }
                    using (MemoryStream ms = new MemoryStream())
                    {
                        if (useCache)
                        {
                            try
                            {
                                bm.Save(cachePath, ImageFormat.Png);
                            }
                            catch { }
                        }
                        bm.Save(ms, ImageFormat.Png);

                        context.Response.Cache.SetCacheability(HttpCacheability.Public);
                        context.Response.Cache.SetExpires(DateTime.Now.AddDays(7));
                        ms.WriteTo(context.Response.OutputStream);
                    }
                }
                finally
                {
                    bm.Dispose();
                    bm2.Dispose();
                }
            }
            else
            {
                Bitmap bm = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
                try
                {
                    Graphics g = Graphics.FromImage(bm);
                    try
                    {
                        g.Clear(MapBackgroundColor);
                        RenderMap(g, mapLayers, 256, 256, centerPoint, zoom);

                        //perform custom painting
                    }
                    finally
                    {
                        g.Dispose();
                    }
                    using (MemoryStream ms = new MemoryStream())
                    {
                        if (useCache)
                        {
                            try
                            {
                                bm.Save(cachePath, ImageFormat.Png);
                            }
                            catch { }
                        }
                        bm.Save(ms, ImageFormat.Png);

                        context.Response.Cache.SetCacheability(HttpCacheability.Public);
                        context.Response.Cache.SetExpires(DateTime.Now.AddDays(7));
                        ms.WriteTo(context.Response.OutputStream);
                    }
                }
                finally
                {
                    bm.Dispose();
                }
            }
            context.Response.Flush();
        }
Esempio n. 30
0
        public override void ActionPerform()
        {
            var painterBrushNum = 0;

            terrain = Map.Terrain;

            painter = Map.Painter;

            tile    = terrain.Tiles[PosNum.X, PosNum.Y];
            texture = tile.Texture;

            terrain.Tiles[PosNum.X, PosNum.Y].TriTopLeftIsCliff     = false;
            terrain.Tiles[PosNum.X, PosNum.Y].TriTopRightIsCliff    = false;
            terrain.Tiles[PosNum.X, PosNum.Y].TriBottomLeftIsCliff  = false;
            terrain.Tiles[PosNum.X, PosNum.Y].TriBottomRightIsCliff = false;
            terrain.Tiles[PosNum.X, PosNum.Y].DownSide = TileUtil.None;

            for (painterBrushNum = 0; painterBrushNum <= painter.CliffBrushCount - 1; painterBrushNum++)
            {
                var a = 0;
                for (a = 0; a <= painter.CliffBrushes[painterBrushNum].Tiles_Straight.TileCount - 1; a++)
                {
                    painterTexture = painter.CliffBrushes[painterBrushNum].Tiles_Straight.Tiles[a];
                    if (painterTexture.TextureNum == texture.TextureNum)
                    {
                        if (tile.Tri)
                        {
                            terrain.Tiles[PosNum.X, PosNum.Y].TriTopLeftIsCliff     = true;
                            terrain.Tiles[PosNum.X, PosNum.Y].TriBottomRightIsCliff = true;
                        }
                        else
                        {
                            terrain.Tiles[PosNum.X, PosNum.Y].TriTopRightIsCliff   = true;
                            terrain.Tiles[PosNum.X, PosNum.Y].TriBottomLeftIsCliff = true;
                        }
                        terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff = true;
                        TileUtil.RotateDirection(painterTexture.Direction, texture.Orientation, ref resultDirection);
                        terrain.Tiles[PosNum.X, PosNum.Y].DownSide = resultDirection;
                    }
                }
                for (a = 0; a <= painter.CliffBrushes[painterBrushNum].Tiles_Corner_In.TileCount - 1; a++)
                {
                    painterTexture = painter.CliffBrushes[painterBrushNum].Tiles_Corner_In.Tiles[a];
                    if (painterTexture.TextureNum == texture.TextureNum)
                    {
                        TileUtil.RotateDirection(painterTexture.Direction, texture.Orientation, ref resultDirection);
                        if (tile.Tri)
                        {
                            if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.TopLeft))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriTopLeftIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff   = true;
                            }
                            else if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.BottomRight))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriBottomRightIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff       = true;
                            }
                        }
                        else
                        {
                            if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.TopRight))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriTopRightIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff    = true;
                            }
                            else if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.BottomLeft))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriBottomLeftIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff      = true;
                            }
                        }
                    }
                }
                for (a = 0; a <= painter.CliffBrushes[painterBrushNum].Tiles_Corner_Out.TileCount - 1; a++)
                {
                    painterTexture = painter.CliffBrushes[painterBrushNum].Tiles_Corner_Out.Tiles[a];
                    if (painterTexture.TextureNum == texture.TextureNum)
                    {
                        oppositeDirection = painterTexture.Direction;
                        oppositeDirection.FlipX();
                        oppositeDirection.FlipY();
                        TileUtil.RotateDirection(oppositeDirection, texture.Orientation, ref resultDirection);
                        if (tile.Tri)
                        {
                            if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.TopLeft))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriTopLeftIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff   = true;
                            }
                            else if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.BottomRight))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriBottomRightIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff       = true;
                            }
                        }
                        else
                        {
                            if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.TopRight))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriTopRightIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff    = true;
                            }
                            else if (TileUtil.IdenticalTileDirections(resultDirection, TileUtil.BottomLeft))
                            {
                                terrain.Tiles[PosNum.X, PosNum.Y].TriBottomLeftIsCliff = true;
                                terrain.Tiles[PosNum.X, PosNum.Y].Terrain_IsCliff      = true;
                            }
                        }
                    }
                }
            }

            Map.SectorTerrainUndoChanges.TileChanged(PosNum);
        }