Подтвердить что ты не робот

Использование пространственных данных Sql (С#) для поиска "визуального" центра нерегулярных многоугольников

Я рисую области (используя SqlGeometry/SqlGeography и переводя их в эквивалент WPF LocationCollection) на Bing Maps WPF Control и должен маркировать их. Я получил метки, нарисованные на регионах, и привязал их к точке, найденной STCentroid(). Конечно, как вы себе представляете, это проблема с областями "U" или "C", где центроид выходит за пределы региона, что делает метку неправильной.

Есть ли способ использовать SqlGeometry/SqlGeography, чтобы найти "визуальный" центр или, возможно, найти самый большой круг, который может вписаться в форму и использовать этот центр? Я пробовал различные методы с помощью STPointOnSurface(), но кажется, что STPointOnSurface() всегда выбирает точку на краю, как, например, DCREHA (ярлык для нижней темно-зеленой области всегда заканчивается по краям:

введите описание изображения здесь

4b9b3361

Ответ 1

Вопрос о почти идентичном вопросе уже был задан здесь. В вашем случае наиболее подходящий ответ, вероятно, this. Трудная часть этого ответа определяет, где рисовать линию, которая разбивает многоугольник на две равные области. Поэтому я предлагаю немного модифицированную версию ниже для SQL Server:

  • Используйте STCentroid, чтобы найти центр масс
  • Если это внутри многоугольника (STWithin), то нет необходимости обрабатывать дальше; в противном случае:
  • Определите центр тяжести прямоугольной рамки (например, используйте STEnvelope для получения огибающей многоугольника и передайте это как аргумент STCentroid)
  • Если этот центроид находится в пределах многоугольника (STWithin), он может быть достаточно хорошим (потребуется тестирование); в противном случае:
  • Расширьте линию, соединяющую центроид многоугольника и центр тяжести огибающей, чтобы он простирался только до полигонального конверта в каждом направлении (может быть проще в коде С# или увидеть здесь для решения PostGIS)
  • Определите точки пересечения между расширенной линией и полигоном (STIntersection)
  • Найдите ближайшую точку пересечения к точке центроида многоугольника с шага 1 (см. здесь). Эта точка является приблизительной для "1-й точки резки", подробно описанной в связанном ответе.
  • Найдите ближайшую точку пересечения с точкой пересечения, найденной выше на шаге 7. Эта точка является приближением для "второй точки резки", подробно описанной в связанном ответе.
  • Средняя точка линии, соединяющей две точки пересечения, будет внутри многоугольника и должна быть разумным приближением для "визуального центра" многоугольника.

Например, учитывая многоугольник для примера DCREHA выше, следующий GIF обновляет описанную выше процедуру (судя по мнению пользователя - фактический результат будет отличаться):

введите описание изображения здесь