Converter longitude / latitude em pixels no mapa

10

Eu tenho um mapa daqui . Eu quero ser capaz de converter simplesmente pares lon / lat arbitrários em pixels no mapa (também a capacidade de fazer a conversão reversa). Os mapas vêm com informações sobre o arquivo .tfw e a projeção, aqui está:

0.02222222222222 
0.00000000000000 
0.00000000000000 
-0.02222222222222 
-180.00000000000000 
90.00000000000000

e informações de projeção:

Projection: Plate Carree aka Geographic or "LatLong"
Earth ellipsoid: Sphere, radius 6370997 m
Datum: WGS84
Extent: 180 West to 180 East, 90 North to 90 South
Size: 16,200 height samples wide x 8,100 high
Resolution: 2.47 km/pixel

Sou completamente novo em assuntos relacionados à cartografia e, tanto quanto descobri, deveria primeiro fazer a transformação de WGS84 (par lon / lat) em projeção geográfica (eles não são os mesmos?). Parece-me que eles são os mesmos, na verdade, mas o raio da esfera nas informações de projeção acima é 6370997 e é diferente da página spatialreference.com que encontrei para a projeção Plate Carree. Enfim, eu achei a biblioteca DotSpatial.Projections pode fazer isso por mim, com o seguinte código:

    var kievCoordinates = new[] { 50.4546600, 30.5238000 };
    var z = new[] { 1.0 };

    var wgs84 = KnownCoordinateSystems.Geographic.World.WGS1984;
    var dest = new ProjectionInfo();
    dest.ParseEsriString(
        "PROJCS[\"WGS 84 / Plate Carree (deprecated)\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Equidistant_Cylindrical\"],PARAMETER[\"central_meridian\",0],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]");

    Reproject.ReprojectPoints(kievCoordinates, z, wgs84, dest, 0, 1);

E então devo converter as coordenadas resultantes em pixels no mapa usando o arquivo world. Estou ciente da seguinte fórmula:

imagem da wikipedia

Mas parece que existem graus e não metros no arquivo mundial e eu não sei o que fazer com eles. Geralmente, estou fazendo as coisas certas? Ou existe uma maneira mais fácil, considerando meus dados?

Dmitry Marchuk
fonte
11
Com base no arquivo mundial, a varredura está usando latitude-longitude e graus como unidades. O tamanho da célula é 0,0222 graus. Isso às vezes é conhecido como pseudo-Plate Carree. O Plate Carree escalaria e converteria os valores em metros. Há também uma mistura de dados chamada WGS84, mas uma esfera com raio = 6370997 é mencionada. Tentando usar o WKID: 4326.
mkennedy
@mkennedy Acho que a fórmula acima aplicada ao arquivo mundial não resultaria em nada de significativo porque foi projetada para metros? Também não sei e pesquisei no Google sem resultado o que significa WKID: 4326.
Dmitry Marchuk

Respostas:

6

Não há transformação entre coordenadas, mas de / para as posições de pixel, assim: assumimos px, py é uma posição de pixel em seu mapa, enquanto geox e geoy são coordenadas do mundo real. Também temos xOff, yOff retirado do tfw, com -180, 90 mais xsize e ysize, com 0,02222222222222, -0,02222222222222

pix2coord(px,py)
    geox = xOff + (px * xsize)
    geoy = yOff + (py * ysize)

coord2pix(geox, geoy)
    px = (geox - xOff) / xsize 
    py = (geoy - yOff) / ysize

as duas pseudo funções acima nos dizem a localização geográfica (geox, geoy) para uma determinada posição de pixel e, acho que foi o que você pediu, a posição de pixel para uma determinada localização geográfica. Isso só é possível porque o "prato de carga" trata graus geográficos com longitude e latitude como coordenadas métricas em um plano (dentro de um sistema de coordenadas retangular). Se você desenhasse a gratícula da Terra, obteria quadrados do mesmo tamanho (e é assim que a sua imagem do mapa parece). Após editar meus erros, agora recebo com lon / lat (50.4546600, 30.5238000) recebo (10370.459803704598, 2676.42902676429). Faça a conversão para inteiro, se você precisar de caracteres de pixel.

Andreas Müller
fonte
px = (geox + xOff) / xsize, para o seu exemplo seria (50.4546600 + (-180)) / 0.02222222222222negativo e aproximadamente igual 5830. O que não é 2113.3936363636362. Por favor, explique mais ou corrija a resposta.
Dmitry Marchuk 22/03
O código original estava em javascript com algumas dependências, vou verificar ...
Andreas Müller
Alterei o código e o texto acima, porque ocorreu um erro ao copiá-lo de um JavaScript.
Andreas Müller