Azure Maps неправильно отображает векторные плитки

У меня возникла проблема с рендерингом многоугольника из источника векторного фрагмента при высоких уровнях масштабирования. Я использую https://github.com/NetTopologySuite/NetTopologySuite.IO.VectorTiles для создания плиток и подтвердил с помощью простого vuejs, используя пакет npm @mapbox/vector-tile, что я вижу то, что ожидается ( простой четырехгранный многоугольник), поэтому я уверен, что векторные плитки мапбокса сгенерированы правильно.

Я добавил 3 разных образца полигонов, которые я создал как отдельную коллекцию объектов в файле json, преобразовал в векторный файл и визуализировал с помощью простого HTML для карт Azure с одним источником векторных листов плюс слоем линии/заливки. Страница также отображает сетку плиток и отображает информацию о плитке.

Каждый образец представляет собой один и тот же многоугольник, но каждый раз немного длиннее. Как показано на изображениях, рендеринг ухудшается с увеличением размера многоугольника.

Моя интуиция подсказывает, что генерация плитки может быть неправильной, но просмотр плитки в отдельном приложении vuejs, похоже, опровергает эту мысль. Конечно, я могу ошибаться, и мне кажется невероятным, что такой простой многоугольник может стать проблемой для azuremaps/maplibre.

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

Редактировать:

Я загрузил те же файлы mvt sample3 в qgis (3.36.3), и они отлично отрисовываются. Тогда это будет означать, что с генерацией тайлов все в порядке, и проблема в рендеринге в Maplibre?

Редактировать 2:

Вот репозиторий плиток для sample3.json: Репозиторий тестовых файлов MVT

Кажется, что Sample1 работает нормально:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "id": 1,
        "featureName": "pedestrian"
      },
      "geometry": {
        "coordinates": [
          [
            [
              153.02303214664835,
              -27.47153798017556
            ],
            [
              153.02361397317628,
              -27.472110106801587
            ],
            [
              153.02413908737213,
              -27.471707568508087
            ],
            [
              153.02356566267133,
              -27.471135439790835
            ],
            [
              153.02303214664835,
              -27.47153798017556
            ]
          ]
        ],
        "type": "Polygon"
      }
    }
  ]
}

Sample2 начинает видеть некоторые проблемы с рендерингом:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "id": 1,
        "featureName": "pedestrian"
      },
      "geometry": {
        "coordinates": [
          [
            [
              153.02303214664835,
              -27.47153798017556
            ],
            [
              153.0239584480898,
              -27.472482826140364
            ],
            [
              153.02448566274165,
              -27.472082152801704
            ],
            [
              153.02356566267133,
              -27.471135439790835
            ],
            [
              153.02303214664835,
              -27.47153798017556
            ]
          ]
        ],
        "type": "Polygon"
      }
    }
  ]
}

Sample3 сейчас довольно плох:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "id": 1,
        "featureName": "pedestrian"
      },
      "geometry": {
        "coordinates": [
          [
            [
              153.02303214664835,
              -27.47153798017556
            ],
            [
              153.0243377004698,
              -27.472866763505785
            ],
            [
              153.0248843639639,
              -27.47245746377172
            ],
            [
              153.02356566267133,
              -27.471135439790835
            ],
            [
              153.02303214664835,
              -27.47153798017556
            ]
          ]
        ],
        "type": "Polygon"
      }
    }
  ]
}

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Azure Maps использует MapLibre для рендеринга векторных плиток под обложками, а MapLibre — это ответвление MapBox GL JS, поэтому я был бы удивлен, если бы проблема возникла именно здесь.

Я подозреваю, что проблема связана с библиотекой NetTopologySuite.IO.VectorTiles. Заглянув в этот репозиторий, я вижу запрос на включение проблемы, которая кажется связанной: https://github.com/NetTopologySuite/NetTopologySuite.IO.VectorTiles/pull/30

Эта проблема также может быть связана: https://github.com/NetTopologySuite/NetTopologySuite.IO.VectorTiles/issues/29

Обновлять:

Когда я изначально попробовал использовать данные GeoJSON для создания плиток, у меня они сработали нормально. Вот почему я попросил вашу плитку. Покопавшись в этом, я обнаружил, что почти каждый рендеринг векторных тайлов, использующий JavaScript/WebGL, имеет проблемы с рендерингом этих тайлов. Осматривая плитку, кажется, что каждая плитка содержит полный исходный многоугольник. Обычно при создании векторных плиток данные, добавляемые в плитку, обрезаются до области, немного превышающей ограничивающую рамку плитки (обычно на несколько пикселей, чтобы обеспечить визуализацию контуров без появления швов плитки). При осмотре ваших плиток кажется, что каждая плитка представляет собой полноугольную форму, что необычно. При увеличении масштаба многоугольник пересекает несколько плиток. Чтобы правильно отобразиться на карте, карта должна обрезать многоугольник в JavaScript. Карта использует библиотеку Earcut, чтобы сделать это быстро, однако она не так точна, как библиотеки, которые обычно используются при создании тайлов. Это компромисс ради производительности. Когда полигоны между тайлами немного перекрываются, этот метод выреза работает нормально, однако, когда перекрытие сильное, как в этом случае, возникают артефакты, которые вы видите. Это также объясняет, почему эти плитки отлично работают в QGIS, поскольку это собственное настольное приложение, которое использует более мощные библиотеки для обрезки полигонов и может выполнять это намного быстрее, чем JavaScript.

Итак, решение этой проблемы — обрезать данные многоугольника в ограничивающую рамку, размер которой немного больше, чем каждый фрагмент, к которому они добавляются. Я делаю это автоматически при создании тайлов просто для повышения производительности, поскольку большинство моих полигонов имеют более 4 координат, поэтому их обрезка снижает сложность данных в каждом тайле и обычно делает их намного меньшими по размеру файла. Я предполагаю, что у вас уже есть код для импорта вашего GeoJSON и чтения его как функций NetTopologySuite. Вот краткий пример того, как взять функцию NetTopologySuite, вырезать ее геометрию и записать ее в плитку.

//Define the tile info.
var tileInfo = new NetTopologySuite.IO.VectorTiles.Tiles.Tile(x, y, zoom);

//Create vector tile for the tile info. Normally you woult use VectorTileTree if creating a tiles over an area.
var vectorTile = new NetTopologySuite.IO.VectorTiles.VectorTile(){
    TileId = tileInfo.Id
};

//Add a layer to the vector tile. 
//As an optimization, you could wait to see if any polygons intersect the tile before adding a layer.
var myDataLayer = new NetTopologySuite.IO.VectorTiles.Layer()
{
    Name = "myDataLayer"
};
vectorTile.Layers.Add(myDataLayer);

//Decide how much to buffer the bounding box of a tile, in percentage.
//Usually a number between 2 and 5 is plenty for lines and polygons.
//For points, you may want to use a higher number depending on size of icons being used.
var tileBufferPercentage = 3; 

//Get a polygon for a buffered bounding box of the tile.
var tilePolygon = tileInfo.ToPolygon(tileBufferPercentage);

//Check to see if the polygon intersects the tile. No sense adding polygon to tile otherwise.
if (polygonFeature.Geometry.Intersects(tilePolygon))
{
    //Clip the polygon to the input polygon, by finding the intersection.
    //Don't overwrite the polygonFeature.Geometry otherwise it will cause issues for other tiles.
    var clippedPolygon = polygonFeature.Geometry.Intersection(tilePolygon);

    //Add the clipped polygon to the layer.
    myDataLayer.Features.Add(new NetTopologySuite.Features.Feature(clippedPolygon, polygonFeature.Attributes));
}

Я согласен с вами @rbrundritt, очень сомнительно, что это Maplibre/mapbox. Это, безусловно, связано с этой проблемой, и именно поэтому я тоже попробовал код извлечения (на самом деле это показанные плитки), но, похоже, не решил проблему, которую я вижу.

Mark 18.06.2024 05:41

Я обновил вопрос информацией о тесте qgis, который работает нормально. Можете ли вы протестировать векторную визуализацию полигона образца 3 с помощью z19 на картах Azure и qgis для сравнения?

Mark 18.06.2024 09:24

Не могли бы вы предоставить векторные тайлы для тестирования? Либо в качестве включенной конечной точки COR, либо в виде загружаемого файла где-нибудь (OneDrive, Dropbox...)

rbrundritt 18.06.2024 16:41

Я добавил репозиторий с файлами mvt, сгенерированными из ветки Issue29 — см. Редактирование 2, о котором идет речь. Спасибо, что заглянули.

Mark 19.06.2024 01:14

Обновленный пост с решением

rbrundritt 19.06.2024 19:25

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

Mark 19.06.2024 23:38

Другие вопросы по теме