Статическое изображение, расположенное далеко на севере, растягивается

В нашем приложении у нас есть серверная часть, которая выполняет некоторую растровую обработку в области карты и отправляет изображение обратно во внешний интерфейс на основе OL, который вставляет изображение в указанном экстенте.

Полигон для обработки отправляется в виде координат GeoJSON (EPSG: 4326) на бэкэнд, который затем преобразует многоугольник в прямоугольную проекцию (EPSG: 3035 в данном случае), выполняет обработку и отправляет результаты тепловой карты обратно во внешний интерфейс в виде Изображение в кодировке PNG, перепроецированное на стороне сервера в формат EPSG: 3857 (для соответствия проекции нашей фоновой карты на основе OSM). Затем изображение вставляется в ImageLayer с помощью объекта ImageStatic, экстент которого вычисляется серверной частью (ограничивающая рамка изображения, преобразованная в EPSG: 3035, преобразованная в EPSG: 3857).

Это нормально работает, за исключением полигонов на крайнем севере Скандинавии. Например, изображение, экстент которого в EPSG: 3857 равен [1684632.9133543067,9544855.787615912,2902401.684702249,10831736.048522325], при добавлении на карту визуализируется следующим образом:

Ошибочно спроецированное изображение

Желательно, чтобы изображение следовало за юго-восточными границами затененного многоугольника. Вместо этого он перекошен и вытянут на северо-восток.

Я был бы очень благодарен за любые идеи и подсказки относительно того, почему это не работает должным образом.


person tgerdin    schedule 02.04.2020    source источник
comment
Не могли бы вы включить соответствующий код геоинструмента и javascript, который добавляет карту?   -  person Ian Turton    schedule 02.04.2020
comment
Если изображение находится в проекции EPSG: 3035, оно должно быть определено с этой проекцией и экстентом и перепроецировано OpenLayers аналогично изображению EPSG: 27700 в этом примере openlayers.org/en/latest/examples/reprojection-image.html   -  person Mike    schedule 03.04.2020
comment
Прямо сейчас мы перепроецируем изображение на серверную часть EPSG: 3857, поэтому экстент указан в EPSG: 3857. Раньше мы использовали перепроецирование на стороне клиента, но перешли на серверное, поскольку оно выглядело более точным. Было бы интересно посмотреть, воспроизводится ли вышеупомянутая проблема с повторным проецированием на стороне клиента, хотя @IanTurton Существует изрядное количество кода, но я могу посмотреть, могу ли я попытаться воспроизвести сокращенную версию частей, которые должны быть актуальными.   -  person tgerdin    schedule 06.04.2020
comment
скорее всего проблема в том, что вы используете 3857 слишком далеко на север   -  person Ian Turton    schedule 06.04.2020
comment
@IanTurton Хм. Разве 3857 не должен быть действительным до 85,06 ° с.ш.? А фоновая карта OSM в проекции 3857 и выглядит нормально в этом регионе?   -  person tgerdin    schedule 07.04.2020
comment
@Mike Я попробовал еще раз, и результаты такие же при использовании перепроецирования на стороне клиента. Я не обученный ГИС-профессионал, поэтому, возможно, я пытаюсь слишком далеко продвинуть EPSG: 3857. Даже в этом случае особенности алгоритма преобразования координат, который я использую на сервере, возможно, имеют значение. Я в основном использую что-то вроде: ReferencedEnvelope roiEnvelope = new ReferencedEnvelope(params.roi.getEnvelopeInternal(), DefaultGeographicCRS.WGS84); Envelope targetEnv = roiEnvelope.transform(input.getCoordinateReferenceSystem2D(), false, 1000);, где params.roi - это геометрия EPSG: 4326 JTS.   -  person tgerdin    schedule 07.04.2020
comment
Модификация приведенного выше, я использую: MathTransform defaultToTarget = CRS.findMathTransform(DefaultGeographicCRS.WGS84, input.getCoordinateReferenceSystem2D(), true); Geometry targetRoi = JTS.transform(params.roi, defaultToTarget); Envelope targetEnv = JTS.bounds(targetRoi, input.getCoordinateReferenceSystem());   -  person tgerdin    schedule 07.04.2020
comment
После обработки проецирую результат (GridCoverage2D) на карту CRS: Envelope dataEnvelope = new ReferencedEnvelope(result.getEnvelope()); CoordinateReferenceSystem mapCRS = CRS.getAuthorityFactory(true).createCoordinateReferenceSystem("EPSG:3857"); MathTransform transform = CRS.findMathTransform(result.getGridGeometry().getCoordinateReferenceSystem(), mapCRS); Envelope targetEnvelope = JTS.transform(dataEnvelope, null, transform, 10000); GridCoverageRenderer renderer = new GridCoverageRenderer(mapCRS, targetEnvelope, result.getGridGeometry().getGridRange2D(), null); ...   -  person tgerdin    schedule 07.04.2020
comment
Возможно, поэкспериментируйте, перепроецируя фон, чтобы проверить правильность экстента изображения codeandbox.io/s/reprojection- image-v6s9j   -  person Mike    schedule 07.04.2020
comment
@Mike Reprojecting фона было бы хорошо для отладки, но не жизнеспособным путем для решения проблемы. Я могу только понять, что проблема в том, что я пытаюсь перепроецировать слишком большую область для имеющейся широты и проекции (3857). Я бы надеялся, что перепроецирование с использованием уплотненного конверта (см. Код выше) поможет, но даже при использовании точек 1e6 я получаю ту же проблему, а также перепроецирование отдельных координат, составляющих ROI, а затем вычисление экстента не решает этого. намного лучше (хотя и немного).   -  person tgerdin    schedule 08.04.2020
comment
Единственное решение, как я вижу сейчас, - это измельчить результат и перепроецировать плитки по отдельности. Было бы неплохо, если бы OpenLayers лучше перепроецировали изображение, поскольку в нем должна быть вся информация (после регистрации EPSG: 3035 в proj4), но, возможно, я чего-то упускаю.   -  person tgerdin    schedule 08.04.2020
comment
Какую версию вы используете? 6.3.0 включает некоторые улучшения в репроекции изображений github.com/openlayers/openlayers/releases /tag/v6.3.0   -  person Mike    schedule 08.04.2020
comment
@Mike Мы используем 6.2.0 атм, я могу попробовать 6.3.0 и посмотреть, улучшится ли что-нибудь.   -  person tgerdin    schedule 09.04.2020
comment
@Mike Пробовал OL 6.3.1, та же проблема. Мой текущий план - максимально обрезать проектируемую площадь, чтобы минимизировать проблему. В противном случае я полагаю, что использование плиточного протокола могло бы помочь, но это потребовало бы значительного объема работы на стороне сервера.   -  person tgerdin    schedule 14.04.2020


Ответы (1)


Я решил эту проблему, максимально обрезав изображение для повторного проецирования. В результате огибающая становится намного меньше, что устраняет искажения. Спасибо за подсказку, @Ian!

person tgerdin    schedule 17.04.2020