Преобразование долготы и широты в пиксельные координаты изображения X, Y в проекции Альбера

#java #geotools

#java #геоинструменты

Вопрос:

Я получаю много координат с радара, эти координаты отформатированы почти так же, как координаты Google Maps, я не совсем уверен, но я спросил компанию, и они сказали мне, чтобы получить координаты в проекции Альбера, мне нужно сделать следующее:

Затем вы сможете создать 2 CoordinateReferenceSystem (т. Е. Системы координат), Установить одну по умолчанию (которая равна lon / lat), а другую — с помощью строки WKT (которая будет проецироваться x / y). Затем вы можете легко создать 2 MathTransform для преобразования в обоих направлениях.

Это OGC WKT для проекции Альбера:

 PROJCS["unnamed",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.2572235629972,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Albers_Conic_Equal_Area"],
    PARAMETER["standard_parallel_1",31.996308],
    PARAMETER["standard_parallel_2",33.996308],
    PARAMETER["latitude_of_center",32.996308],
    PARAMETER["longitude_of_center",35.415901],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    UNIT["metre",1,AUTHORITY["EPSG","9001"]]]
  

Итак, из того, что я получаю, мне нужно преобразовать из long / lat в эту проекцию WKT, чтобы отобразить на изображении проекционной карты Альбера.

Итак, в GeoTools я использовал следующий код:

     CoordinateReferenceSystem source = CRS.decode("EPSG:4326");
    CoordinateReferenceSystem target = CRS.parseWKT("PROJCS["unnamed", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.2572235629972, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0], UNIT["degree",0.0174532925199433], AUTHORITY["EPSG","4326"]], PROJECTION["Albers_Conic_Equal_Area"], PARAMETER["standard_parallel_1",31.996308], PARAMETER["standard_parallel_2",33.996308], PARAMETER["latitude_of_center",32.996308], PARAMETER["longitude_of_center",35.415901], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["metre",1,AUTHORITY["EPSG","9001"]]]");
    MathTransform transform = CRS.findMathTransform(source, target, true);

    Coordinate c = JTS.transform(new Coordinate(34, 35), new Coordinate(), transform);
    System.out.println(c.toString());
  

И это результат, который я получаю:

 (-38422.86847540497, 111410.0483012808, NaN)
  

Теперь это может быть из-за неправильной исходной системы координат, но что он имел в виду под системой long / lat по умолчанию?

Даже если я решу эту проблему, как я могу заставить ее отображать эти точки на моем изображении карты? Я имею в виду, что он должен знать ширину / высоту изображения, не так ли?

Ответ №1:

Эта проекция Альберса WKT проецируется из EPSG 4326 на расстояние в метрах от нулевой точки (см. Параметры). Как мы узнаем, что это метры? поскольку в WKT есть метка set UNIT, отображающая его как единицу измерения.

Итак, как я это использовал?

Моя компания предоставила мне два файла: файл map JPEG и XML-файл для констант карты.

Этот XML-файл с константами карты содержит расстояние от нулевой точки этой карты до углов карты. Итак, если у вас есть хотя бы одна точка на карте, вы можете найти все.

Что нужно знать, чтобы преобразовать его в карту X / Y:

  • Сколько километров составляет каждый пиксель (в моем случае 1,6 ровно 1 миля)
  • по крайней мере, одна известная точка на карте на расстоянии от нулевой точки

Вот как я это сделал:

         MathTransform transform = CRS.findMathTransform(epsg4326, targetWKT, true);

        DirectPosition2D srcDirectPosition2D
                = new DirectPosition2D(epsg4326, latitude, longitude);
        DirectPosition2D destDirectPosition2D
                = new DirectPosition2D();
        transform.transform(srcDirectPosition2D, destDirectPosition2D);

        double transX = destDirectPosition2D.x;
        double transY = destDirectPosition2D.y;

        int kmPerPixel = mapImage.getWidth / 1024; // It is known to me that my map is 1024x1024km ...

        double x = zeroPointX   ( (transX * 0.001) * kmPerPixel);
        double y = zeroPointY   ( ( (transX * -1) * 0.001) * kmPerPixel);
  

Нулевые точки X и Y вы можете получить, выполнив те же вычисления без добавления, в точке, которую вы имеете на карте, на расстоянии, как я сделал с моим углом.

Может помочь некоторым людям, поэтому я опубликовал то, что выяснил.