Давно интересовал вопрос, что можно оригинального нарисовать в  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) 
 |   
Маляр красит стенку в сумашедшем доме . Подходит псих : -Ты крепко за кисточку держишься ? -Да - отвечает тот . -Тогда я   лестницу забираю. 









