0

私はこのように見えるいくつかのデータを持っています:

<?xml version="1.0" encoding="utf-8"?>
<levels>
  <level nr="0" tileWidth="512" tileHeight="512" envSizeX="5000" envSizeY="5000" minX="465000" maxX="470000" minY="105000" maxY="110000" scaleFactor="1" tilesCountX="10" tilesCountY="10" />
  <level nr="1" tileWidth="512" tileHeight="512" envSizeX="4613" envSizeY="4613" minX="465000" maxX="469999" minY="105001" maxY="110000" scaleFactor="1.0837333333333332" tilesCountX="10" tilesCountY="10" />
  <level nr="2" tileWidth="512" tileHeight="512" envSizeX="2286" envSizeY="2286" minX="465000" maxX="469955" minY="105045" maxY="110000" scaleFactor="2.1674666666666664" tilesCountX="5" tilesCountY="5" />
  <level nr="3" tileWidth="512" tileHeight="512" envSizeX="1134" envSizeY="1134" minX="465000" maxX="469915" minY="105085" maxY="110000" scaleFactor="4.3349333333333329" tilesCountX="3" tilesCountY="3" />
  <level nr="4" tileWidth="512" tileHeight="512" envSizeX="563" envSizeY="563" minX="465000" maxX="469879" minY="105121" maxY="110000" scaleFactor="8.6698666666666657" tilesCountX="2" tilesCountY="2" />
  <level nr="5" tileWidth="512" tileHeight="512" envSizeX="275" envSizeY="275" minX="465000" maxX="469777" minY="105223" maxY="110000" scaleFactor="17.339733333333331" tilesCountX="1" tilesCountY="1" />
  <level nr="6" tileWidth="512" tileHeight="512" envSizeX="134" envSizeY="134" minX="465000" maxX="469658" minY="105342" maxY="110000" scaleFactor="34.679466666666663" tilesCountX="1" tilesCountY="1" />
  <level nr="7" tileWidth="512" tileHeight="512" envSizeX="67" envSizeY="67" minX="465000" maxX="469623" minY="105377" maxY="110000" scaleFactor="69.358933333333326" tilesCountX="1" tilesCountY="1" />
  <level nr="8" tileWidth="512" tileHeight="512" envSizeX="33" envSizeY="33" minX="465000" maxX="469554" minY="105446" maxY="110000" scaleFactor="138.71786666666665" tilesCountX="1" tilesCountY="1" />
  <level nr="9" tileWidth="512" tileHeight="512" envSizeX="16" envSizeY="16" minX="465000" maxX="469432" minY="105568" maxY="110000" scaleFactor="277.4357333333333" tilesCountX="1" tilesCountY="1" />
  <level nr="10" tileWidth="512" tileHeight="512" envSizeX="8" envSizeY="8" minX="465000" maxX="469432" minY="105568" maxY="110000" scaleFactor="554.87146666666661" tilesCountX="1" tilesCountY="1" />
</levels>

このデータを使用して、タイルの範囲(、、、、)を指定する必要がminXあります。レベルを取得してそのタイルを計算するメソッドを作成しました。次に、タイルを取得し、ビューポート領域に属するタイルを選択します。maxXminYmaxY

すべてがうまくいくと思いましたが、データの違いに気づきました(ファイルGdalInfoのメタデータからのデータTIFFとカウント値を比較すると、いくつかの違いがあります...

例えば
GDAL_INFO = 465000, 465554.871466667, 109445.128533333, 110000
MY_EXTENTS = (465000, 465499.9, 105001, 105500.9)

これが私の方法です:

public static IEnumerable<Envelope> GetTiles(string xmlFileName, int level, Rect viewportData, bool debug = false)
{
    // viewport data
    double x = viewportData.X, y = viewportData.Y;
    double width = viewportData.Width, height = viewportData.Height;

    // load level data
    XDocument doc = XDocument.Load(xmlFileName);
    if (doc == null)
    {
        throw new FileNotFoundException("File '" + xmlFileName + "' not found.");
    }

    XElement levelData =
        doc.Element("levels")
            .Descendants()
            .First(element => int.Parse(element.Attribute("nr").Value) == level);

    double minX = double.Parse(levelData.Attribute("minX").Value);
    double maxX = double.Parse(levelData.Attribute("maxX").Value);
    double minY = double.Parse(levelData.Attribute("minY").Value);
    double maxY = double.Parse(levelData.Attribute("maxY").Value);

    int tilesCountX = int.Parse(levelData.Attribute("tilesCountX").Value);
    int tilesCountY = int.Parse(levelData.Attribute("tilesCountY").Value);

    Envelope[][] extents = new Envelope[tilesCountX][];

    Envelope bounds = new Envelope();
    bounds.MinX = 0;
    bounds.MaxX = 0;
    bounds.MinY = 0;
    bounds.MaxY = 0;
    for (int i = 0; i < extents.Length; i++)
    {
        extents[i] = new Envelope[tilesCountY];
        for (int j = 0; j < extents[i].Length; j++)
        {
            // count extents for pieces
            double tileGeoWidth = (maxX - minX)/(double) tilesCountX;
            double tileGeoHeight = (maxY - minY)/(double) tilesCountY;
            double offsetX = (double) j*tileGeoWidth;
            double offsetY = (double) i*tileGeoHeight;

            extents[i][j] = new Envelope();
            extents[i][j].MinX = minX + offsetX;
            extents[i][j].MaxX = minX + tileGeoWidth + offsetX; // poprawic dla ostatnich (niewymiarowych) tilesow
            extents[i][j].MinY = minY + offsetY;
            extents[i][j].MaxY = minY + tileGeoHeight + offsetY;

            // check if a piece matches to the viewport
            // 1. find geo-bounds
            if (offsetX <= x)
                bounds.MinX = offsetX;
            if (offsetX <= x + width)
                bounds.MaxX = offsetX;
            if (offsetY <= y)
                bounds.MinY = offsetY;
            if (offsetY <= y + height)
                bounds.MaxY = offsetY;
        }
    }

    // 2. increase "max" bounds (+ width/height)
    bounds.MaxX += width;
    bounds.MaxY += height;

    var intersectedTiles =
        extents
        .SelectMany(es => es)
        .Where(e => EnvIntersects(e, bounds))
        .ToList();

    if (debug)
    {
        Console.WriteLine("GLOBAL_EXTENT = {0}, {1}, {2}, {3}", minX, maxX, minY, maxY);
        Console.WriteLine("TILES_COUNT = {0}/{1}", tilesCountX, tilesCountY);
        for (int i = 0; i < extents.LongLength; i++)
        {
            for (int j = 0; j < extents.Length; j++)
            {
                Console.WriteLine("EXTENTS = ({0}, {1}, {2}, {3})", extents[i][j].MinX, extents[i][j].MaxX, extents[i][j].MinY, extents[i][j].MaxY);
            }
        }
        foreach (Envelope intersectedTile in intersectedTiles)
        {
            Console.WriteLine("INTERSECTION = ({0}, {1}, {2}, {3})", intersectedTile.MinX, intersectedTile.MaxX,
                              intersectedTile.MinY, intersectedTile.MaxY);
        }
    }

    return intersectedTiles;
}

そして、呼び出し例:

Rect viewportData = new Rect(100000, 200000, 70000, 50000); 
GdalRetile.GetTiles(@"D:\#PYRAMID\su60ne.xml", 1, viewportData, true);

誰かが私がこのコードを修正するのを手伝ってもらえますか?
前もって感謝します!

4

1 に答える 1

0

Ok。私はそれを自分でやった...再びxDDD多分コードは将来some1に役立つでしょう:)

public static IEnumerable<Envelope> GetTiles(string xmlFileName, int level, Rect viewportData, bool debug = false)
{
    // viewport data
    double x = viewportData.X, y = viewportData.Y;
    double width = viewportData.Width, height = viewportData.Height;

    // load level data
    XDocument doc = XDocument.Load(xmlFileName);
    if (doc == null)
    {
        throw new FileNotFoundException("File '" + xmlFileName + "' not found.");
    }

    XElement levelData =
        doc.Element("levels")
            .Descendants()
            .First(element => int.Parse(element.Attribute("nr").Value) == level);

    double minX = double.Parse(levelData.Attribute("minX").Value);
    double maxX = double.Parse(levelData.Attribute("maxX").Value);
    double minY = double.Parse(levelData.Attribute("minY").Value);
    double maxY = double.Parse(levelData.Attribute("maxY").Value);

    int tilesCountX = int.Parse(levelData.Attribute("tilesCountX").Value);
    int tilesCountY = int.Parse(levelData.Attribute("tilesCountY").Value);

    double scaleFactor = double.Parse(levelData.Attribute("scaleFactor").Value);
    double rasterXSize = double.Parse(levelData.Attribute("rasterXSize").Value);
    double rasterYSize = double.Parse(levelData.Attribute("rasterYSize").Value);
    double lastTileXSize = double.Parse(levelData.Attribute("lastTileXSize").Value);
    double lastTileYSize = double.Parse(levelData.Attribute("lastTileYSize").Value);

    Envelope[][] extents = new Envelope[tilesCountX][];

    Envelope bounds = new Envelope();
    bounds.MinX = 0;
    bounds.MaxX = 0;
    bounds.MinY = 0;
    bounds.MaxY = 0;

    double tileGeoWidth = rasterXSize * scaleFactor;
    double tileGeoHeight = rasterYSize * scaleFactor;
    for (int i = 0; i < extents.Length; i++)
    {
        double offsetY = (double) i*tileGeoHeight;
        extents[i] = new Envelope[tilesCountY];
        for (int j = 0; j < extents[i].Length; j++)
        {
            // count extents for pieces
            double offsetX = (double) j*tileGeoWidth;

            extents[i][j] = new Envelope();
            extents[i][j].MinX = minX + offsetX;
            extents[i][j].MinY = minY + offsetY;
            extents[i][j].MaxX = minX + tileGeoWidth + offsetX;
            extents[i][j].MaxY = minY + tileGeoHeight + offsetY;

            // last tiles are cut
            if (j == extents[i].Length - 1)
            {
                extents[i][j].MaxX -= (rasterXSize - lastTileXSize);
                extents[i][j].MinY -= (rasterYSize - lastTileYSize);
            }

            // check if a piece matches to the viewport
            // 1. find geo-bounds
            if (offsetX <= x)
                bounds.MinX = offsetX;
            if (offsetX <= x + width)
                bounds.MaxX = offsetX;
            if (offsetY <= y)
                bounds.MinY = offsetY;
            if (offsetY <= y + height)
                bounds.MaxY = offsetY;
        }
    }

    // 2. increase "max" bounds (+ width/height)
    bounds.MaxX += width;
    bounds.MaxY += height;

    var intersectedTiles =
        extents
        .SelectMany(es => es)
        .Where(e => EnvIntersects(e, bounds))
        .ToList();

    if (debug)
    {
        Console.WriteLine("GLOBAL_EXTENT = {0}, {1}, {2}, {3}", minX, maxX, minY, maxY);
        Console.WriteLine("TILES_COUNT = {0}/{1}", tilesCountX, tilesCountY);
        for (int i = 0; i < extents.LongLength; i++)
        {
            for (int j = 0; j < extents.Length; j++)
            {
                Console.WriteLine("EXTENTS = ({0}, {1}, {2}, {3})", extents[i][j].MinX, extents[i][j].MaxX, extents[i][j].MinY, extents[i][j].MaxY);
            }
        }
        foreach (Envelope intersectedTile in intersectedTiles)
        {
            Console.WriteLine("INTERSECTION = ({0}, {1}, {2}, {3})", intersectedTile.MinX, intersectedTile.MaxX,
                              intersectedTile.MinY, intersectedTile.MaxY);
        }
    }

    return intersectedTiles;
}
于 2012-10-01T08:32:58.647 に答える