Давно интересовал вопрос, что можно оригинального нарисовать в SQL, кроме квадрата Малевича конечно...
С эти вопросом я отправился к поисковому серверу.
Вдохновившись найденными скриптами в интернете, я решил исследовать эту тему дальше.
У SQL Server 2008 есть специальная вкладка для просмотра графических данных.
К сожалению редактора для рисования таких картинок я так и не нашел
Но у далось выяснить много интересного…
Типы geometry и geography
Для работы с пространственными типами данных еще в SQL Server 2008, появилось два типа geography и geometry.
Очень подробно работа с этими типами описана в книге Aitchison A. - Pro Spatial with SQL Server 2012
Тип данных geometry применяется к плоским фигурам и имеет отношение к Евклидовой геометрии, где все объекты располагаются на плоской поверхности. Для координат на плоскости используются координаты X,Y иногда и Z.
Тип данных geography используется для задания фигур, объектов и определения расстояния в условиях поверхности земли, т.е с учетом формы земли которая, как известно, является приплюснутым сфероидом.
Для координат на поверхности земли используется долгота и широта и привязка к системе координат SRID (датуму , который представляет собой набор параметров смещения и поворота эллипсоида для лучшей аппроксимации земной поверхности. Также датум задаёт нулевой меридиан, от которого будет идти отсчёт долготы)
В настоящий момент практически все географические сервисы используют единую систему присвоения точке координат — WGS 84, он идет под кодом 4326
Ниже пример как перевести координаты из сферической системы в плоскую.
Математически она выражается следующим образом (для сферы):
x = R · λ;
y = R · ln(tg(π/4 + φ/2), где R — радиус сферы, λ — долгота в радианах, φ — широта в радианах.
y = R · ln(tg(π/4 + φ/2), где R — радиус сферы, λ — долгота в радианах, φ — широта в радианах.
На выходе получаем обычные декартовы координаты в метрах.
Скрипт ниже хорошо демонстрирует эти различия, в случае с типом география расстояния равно 635760 метров, что равняется 635 км в соответствии с нашим идентификатором координат 4326 uint_of_measure = metre
Конвертировать напрямую из типа geography в тип geometry напрямую не получится, для этого нужно использовать формулы трансформации, которые описаны в книге.
--Тип география
DECLARE @MoscowGeog AS GEOGRAPHY= geography::Point(55.755787,37.617634, 4326);
DECLARE @SPetersburgGeog AS GEOGRAPHY= geography::Point(59.939037,30.315784, 4326);
--Тип геометрия, напрямую нельзя конвертировать SELECT CAST(@MoscowGeog AS geometry);
--DECLARE @MoscowGeom as geometry = geometry::STGeomFromWKB(@MoscowGeog.STAsBinary(), @MoscowGeog.STSrid);
--DECLARE @SPetersburgGeom as geometry = geometry::STGeomFromWKB(@SPetersburgGeog.STAsBinary(), @SPetersburgGeog.STSrid);
DECLARE @MoscowGeom as geometry = geometry::Point(6179494,413470,0);
DECLARE @SPetersburgGeom as geometry = geometry::Point(6647711,351165, 0);
SELECT @MoscowGeog.STDistance(@SPetersburgGeog) As 'Расстояние Москва-Санкт Петербург', @MoscowGeog.ToString() WKT, @MoscowGeog.Lat "широта", @MoscowGeog.Long "долгота", @MoscowGeog.STSrid as STSrid
UNION ALL
SELECT @MoscowGeom.STDistance(@SPetersburgGeom) As 'Расстояние Москва-Санкт Петербург', @MoscowGeom.ToString() , @MoscowGeom.STY, @MoscowGeom.STX , @MoscowGeom.STSrid
GO
--Идентификатор пространственной привязки (SRID) - это уникальный идентификатор, соответствующий привязке к определенной системе координат
--список всех идентификаторов находится в таблице sys.spatial_reference_systems
SELECT * FROM sys.spatial_reference_systems t WHERE t.spatial_reference_id = 4326
|
Список всех идентификаторов можно найти в таблице spatial_reference_systems
SQL сервер поддерживает следующие способы задания геометрических объектов, самый простой понятный и наглядный это WKT его и будем дальше использовать .
WKT (WELL KNOWN TEXT, известный текстовый формат, применяемый для описания графических объектов), WKB является двоичным эквивалентом формата WKT и
GML (geography markup language, язык географической разметки)
В 2012 появились окружности и дуги CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4)
Чтобы задать элемент можно воспользоваться одной из четырех форм записи
--Precise Spatial method
SET @g = GEOMETRY::STPolyFromText('POLYGON( (0 0, 30 0, 30 30, 0 30, 0 0)) ',4326);
--Generic Spatial method
SET @g = GEOMETRY::STGeomFromText('POLYGON( (0 0, 30 0, 30 30, 0 30, 0 0)) ',4326);
--Short Format
SET @g = 'POLYGON( (0 0, 30 0, 30 30, 0 30, 0 0) )';
-- CLR form
Для типа Geometry кстати предусмотрено очень много полезных методов
По ссылке можно найти полное описание
Вычисляет площадь
| |
Возвращает представление в формате WKB
| |
Возвращает WKT-представление OGC
| |
Возвращает все границы объекта
| |
Расширяет объект на зону буфера
| |
Возвращает геометрический центр
| |
Содержит объект в себе geometry
| |
Возвращает выпуклую оболочку экземпляра geometry.
| |
Возвращает 1 если объекты пересекаются
| |
Возвращает кривую, указанную в экземпляре geometry
| |
Вычитает из объекта другой объект geometry
| |
Определяет точка, линия или полигон
| |
Возвращает наименьшее расстояние между объектами
| |
Возвращает конечную точку экземпляра geometry.
| |
Возвращает прямоугольник вокруг объекта
| |
проверяет совпадают ли объекты
| |
Возвращает внешнюю границу объекта
| |
Возвращает указанный номер элемента в коллекции
| |
Возвращает имя типа OGC (точка, линия, полигон, кривая)
| |
Возвращает внутреннюю границу объекта
| |
Возвращает пересечение двух объектов
| |
Возвращает 1 если объекты пересекаются
| |
Возвращает 1, если начальная и конечная точки совпадают
| |
Возвращает значение 1, если экземпляр geometry пуст
| |
Возвращает 1, если экземпляр является кольцом
| |
Возвращает 1, если экземпляр является простым
| |
Проверяет является ли экземпляр правильного формата
| |
Возвращает общую длину элементов в экземпляре
| |
Возвращает количество геометрических объектов
| |
Возвращает суммарное количество точек в каждой из фигур в экземпляре.
| |
Возвращает 1, если экземпляр перекрывает другой экземпляр
| |
Возвращает конкретную точку в экземпляре geometry.
| |
Возвращает произвольную точку, которая находится внутри экземпляра
| |
Возвращает 1, если экземпляр связан с другим экземпляром
| |
идентификатор пространственной ссылки экземпляра
| |
Возвращает начальную точку экземпляра
| |
Возвращает объект, представляющий все точки, принадлежащие одному из экземпляров, но не лежащие одновременно в обоих экземплярах.
| |
Возвращает значение 1, если экземпляр пространственно соприкасается с другим экземпляром
| |
Возвращает объект, представляющий объединение
| |
Возвращает 1, если экземпляр находится полностью в другом экземпляре
| |
Свойство координаты по оси X экземпляра Point
| |
Свойство координаты по оси Y экземпляра Point
|
Новые возможности в SQL 2012
В 2012 появились окружности и дуги CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4), методы ShortestLineTo(), STIsValid(), IsValidDetailed(), MakeValid()
Поддержка полной модели земли а не полушария (В 2008 можно отобразить данные в запросе если они находятся в одном полушарии)
-- Construct a new FullGlobe object (a WGS84 ellipsoid)
DECLARE @Earth geography = 'FULLGLOBE'
-- Calculate the area of the earth
SELECT PlanetArea = @Earth.STArea()
Подробно можно узнать здесь
Пример использования функций
DECLARE @p as GEOMETRY = 'POLYGON((50 0, 60 30, 80 20, 70 40, 100 50, 70 60, 80 80, 60 70,
50 100, 40 70, 20 80, 30 60, 0 50, 30 40, 20 20, 40 30, 50 0 ))'
SELECT @p as geom
UNION ALL
SELECT @p.BufferWithTolerance(-2,2,0) /* 0, tolerance (2nd parm) is the absolute maximum variation in the
ideal buffer distance for the returned linear approximation. */
UNION ALL
SELECT @p.BufferWithTolerance(-9,3,1) /* 1, tolerance is relative. Product of the tolerance parameter
& the diameter of the bounding box */
UNION ALL
SELECT @p.STBuffer(-14)
|
Маляр красит стенку в сумашедшем доме . Подходит псих : -Ты крепко за кисточку держишься ? -Да - отвечает тот . -Тогда я лестницу забираю.