SharePoint 2013. Тип поля Geolocation

1 сентября 2012 г.

В SharePoint 2013 появился новый тип поля, предназначенный для работы с географическими данными. Называется он Geolocation (Geographic location that represents a point on a map). Также появился новый тип представления, предназначенный для отображения данных списка на карте.

Для отображения данных используются карты Bing Maps. В представлении списка просмотр данных осуществляется с использованием callout'ов:

Тип поля Geolocation в SharePoint 2013

А вот так в SharePoint 2013 Preview выглядит представление списка в виде карты: Представление списка в виде карты в SharePoint 2013

Не для пользователей

В Preview версии SharePoint 2013 изначально нет возможности добавить столбец этого типа в список/библиотеку. Это связано с тем, что в SharePoint'е изначально нет такого поля. Тип поля есть, а поля такого типа нет. На MSDN есть статья о том, как добавить поле Geolocation в список программно, используя клиентскую модель SharePoint. Но этот способ, как минимум, некрасивый. Значит нужен другой.

Geolocation field solution

Чтобы реализовать поддержку типа поля Geolocation как в самом SharePoint 2013 для конечных пользователей, так и в Visual Studio 2012 для разработчиков достаточно создать крохотный sandbox solution, который будет содержать один единственный элемент - колонку типа Geolocation. Все решение укладывается в 10 строк:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Elements xmlns="http://schemas.microsoft.com/sharepoint/">  
  3.   <Field
  4.         ID="{43db0e75-7489-4e6e-89d2-14c6cf26252f}"
  5.         Name="GeolocationColumn"
  6.         DisplayName="Geolocation Column"
  7.         Type="Geolocation"
  8.         Group="Geolocation">
  9.   </Field>
  10. </Elements>

Развернув это решение на портале, мы получаем возможность добавлять колонки типа Geolocation в списки/библиотеки:

Добавление поля Geolocation

А также обеспечиваем доступность его в конструкторе типа содержимого в Visual Studio 2012:

Добавление поля Geolocation в Visual Studio 2012

Одно крохотное решение, которое можно развернуть даже удаленно (т.к. это sanbox) и никакого танца с бубном (пользоваться консольным приложениям, чтобы добавить столбец в список!)

Geolocation изнутри

В объектной модели SharePoint поле Geolocation представлено классом SPFieldGeolocation, который унаследован напрямую от SPField, т.е. не завязан ни на какие другие типы полей:

Для хранения значений в таблице dbo.AllUserData есть всего два столбца типа geography. Так что, добавив всего третий столбец такого типа в список, данные в таблице будут занимать по две строки на каждый элемент, что снизит производительность. Хотелось бы, чтобы в следующих версиях кол-во столбцов для хранения географических данных увеличилось. Таблица dbo.AllUserData теперь является wide-таблицей и содержит более 4000 столбцов! Так что пара-тройка дополнительных полей для географических данных - пустяк.

Работа с данными Geolocation

Теперь пара примеров работы с данными нового типа. В SharePoint 2013 появился новый класс, представляющий возможность работы с географическими данными - SPFieldGeolocationValue:

  1. var web = SPContext.Current.Web;
  2. var list = web.GetList("GeoLocationDemoList");
  3. var item = list.GetItemById(1);
  4. var geoVal = item["GeoField"as SPFieldGeolocationValue;
  5. if (geoVal != null)
  6. {
  7.     var lat = geoVal.Latitude;
  8.     var lon = geoVal.Longitude;
  9.     var mes = geoVal.Measure;
  10.     var alt = geoVal.Altitude;
  11. }

Здесь все предельно просто. Можно задавать значения для широты (Latitude), долготы (Longitude), масштаба (Measure) и высоты (Altitude). Класс SPFieldGeolocationValue имеет полный набор конструкторов для создания нового значения поля:

  1. public SPFieldGeolocationValue();
  2. public SPFieldGeolocationValue(string fieldValue);
  3. public SPFieldGeolocationValue(double latitude, double longitude);
  4. public SPFieldGeolocationValue(double latitude, double longitude, 
  5.                                double altitude, double measure);

fieldValue здесь имеет следующий формат: POINT ({Latitude}, {Longitude} [{Measure}, {Altitude}]). В таком же формате можно получить данные, вызвав метод ToString объекта SPFieldGeolocationValue.

Geolocation и Linq to SharePoint

Linq to SharePoint, начиная с 15 версии, умеет работать с geolocation полями. Это единственное нововведение в Linq to SharePoint 2013 :(. SPMetal для полей geolocation генерирует примерно следующий код:

  1. [Microsoft.SharePoint.Linq.ColumnAttribute(Name = "Geolocation"
  2.                   Storage = "_geo", FieldType = "Geolocation")]
  3. public string Geo
  4. {
  5.     get
  6.     {
  7.         return this._geo;
  8.     }
  9.     set
  10.     {
  11.         if ((value != this._geo))
  12.         {
  13.             this.OnPropertyChanging("Geo"this._geo);
  14.             this._geo = value;
  15.             this.OnPropertyChanged("Geo");
  16.         }
  17.     }
  18. }
  19. private string _geo;

Т.е. данные будут представлены в виде простого текста, в вышеописанном формате. Для работы с данными можно инкапсулировать в своем классе функционал из класса SPFieldGeolocationValue.

Но есть и другой способ. Данные типа geography описаны в сборке Microsoft.SqlServer.Types.dll, которая поставляется вместе с SQL Server'ом. В моем случае она располагалась по адресу: C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies. Класс для работы с данными geography называется SqlGeography, конструктор которого также умеет принимать географические данные в виде текста:

  1. var Geography = SqlGeography.Parse(item.Geo);
  2. var lat = Geography.Lat;
  3. var lon = Geography.Long;

Этот класс пригодится для реализации сложной логики при работе с географическими данными. Напоследок скажу, что данные geolocation фильтрации и сортировки не подлежат. Но здесь, я думаю тоже есть варианты обойти это ограничение. Об этом будет отдельный пост в скором будущем (решение задачи поиска ближайшего банкомата, например).

Поделиться

Комментарии