пятница, 31 октября 2008 г.
ВКонтактеId
вторник, 21 октября 2008 г.
Электронная таблица с помощью ANTLR
В рамках тестового задания для одной компании ;) мне надо было реализовать простую электронную таблицу. Простую-то простую, но поддерживающую адресацию отдельных ячеек (A1), диапазонов (A1:Z1), вычисление как простых арифмитических операций ( +, –, *, /), так и функций (SUM, MIN, MAX) и выражений свертки (REDUCE). Последнее описывает действия выполняемые над диапазоном ячеек с использованием накопленного (агрегатного) и текущих значений, например REDUCE(A1:Z1, 1, X*Y) вычислит произведение всех ячеек из диапазона A1:Z1.
Но прежде чем вычислить что-то, надо понять что – т.е. распарсить текстовый вход и построить на основе него AST (Abstract Syntax Tree) – абстрактное синтаксическое дерево. Т.е. независимую от какого-то языка модель описывающую небоходимый набор выражений, и только потом спроецировать ее (реализовать) на конкретном языке программирования и вычислить. Или необязательно программирования, и необязательно вычислить – а например просто распечатать в структурированном виде.
Так вот, для этого незаменимым и эффективным инструментом оказался ANTLR. Универсальный генератор лексеров и парсеров. С помощью специального языка можно описать грамматику вашего языка (в моем случае формулы вичисления и адресации ячеек) и получить готовые исходники на вашем языке программирования (C#, Java, C и т.д.) для его лексического и синтаксичесго анализа.
Ну а после того как разобранное дерево выражений было готово – построить его вычисление было уже делом техники. В технику входило использование LINQ Expressions и лямбд из .NET 3.5 :).
пятница, 10 октября 2008 г.
GeoRSS и его использование на Virtual Earth и Google Maps
GeoRSS это еще один пример удачного расширения формата RSS (я уже рассказывал о других удачных расширениях). Этот формат позволяет встраивать информацию о географическом положении объектов, так называемый геокодинг. Многие сервисы уже начинают использовать эту информацию – и как поставщики, например FLickr выставляет данные о месте, где сделана фотография, если таковая имеется, и как потребители, например в Google Maps можно ввести адрес потока rss с геоданными и он их покажет. Или интересный сервис Panaramio, ототого же Гугла, и как поставщик и как потребитель GeoRSS, здесь можно посмотреть фотографии интересных мест (необязательно известных), сделанные самими пользователями.
Ну с теорией достаточно, теперь посмотрим как это можно сделать на своем сайте (конечно с помощью .NET :) ).
Во-первых, генерация RSS потока с нужными расширенями. Тут ничего нового. Как я описывал уже, с помощью SyndicationFeed и LINQ for XML это очень просто. Есть и готовые обертки для генерации GeoRSS данных.
Во-вторых, нам надо показывать эти данные у себя на сайте. Мне известны два популрных картограцических сервисов с API для встраивания карт у себя – Google Maps от Гугл и Virtual Earth от Майкрософт. Оба сервиса имеют функциональность показа GeoRSS потоков. Как не удивительно, но у Майкрософт с этим удобнее и больше контроля над покащываемыми данными.
На Google Maps достаточно добавить специальный слой и всё.
// The GGeoXml constructor takes a URL pointing to a KML or GeoRSS file.
// You add the GGeoXml object to the map as an overlay, and remove it as an overlay as well.
// The Maps API determines implicitly whether the file is a KML or GeoRSS file.
function initialize()
{
if (GBrowserIsCompatible())
{
map = new GMap2(document.getElementById("map_canvas"));
geoXml = new GGeoXml(http://mapgadgets.googlepages.com/cta.kml);
map.addControl(new GLargeMapControl());
map.addOverlay(geoXml);
}
}
Но под “всё” имеено всё и заканчивается. Больше никакой информации мы не имеем, ни количество объектов, ни их расположение, ничего. Какие-то свойства мы может контролировать в самом RSS потоке, как цвета, иконки и т.д. Но если, например, мы используем внешний фид, с третего сайта – этого ничего нам недоступно.
На Virtual Earth мы также можем добавить специальный слой на карту
var veLayerSpec = new VELayerSpecification();
veLayerSpec.Type = VELayerType.GeoRSS;
veLayerSpec.ID = 'Hazards';
veLayerSpec.LayerSource = 'http://localhost/hazards/hazards.xml';
veLayerSpec.Method = 'get';
veLayerSpec.IconUrl = 'hazard.gif';
map.AddLayer(veLayerSpec);
или импортировать объекты из GeoRSS потока в существующий слой
var slGeoRSS= new VEShapeLayer();
var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS, url, slGeoRSS);
map.ImportShapeLayerData(veLayerSpec, null, false);
При этом у нас имеются события при ипорте, где мы можем получить доступ ко все объектам из RSS и поменять их, как нам захочется.
Еще смежной, но отдельной темой, с которой я столкнулся при работе над проектами моих заказчиков – это хранение и показ собственных географических данных на картах. В предыдущих примерах имелось ввиду что геоданные у нас имеются, причем в нужном формате для GeoRSS. Так вот, чтобы они действительно имелись, очень удобно оказалось использовать новый тип географических данных в Microsoft SQL Server 2008. Так называемый Spatial data type, куда входит geometry тип и geography тип. Но об этом как-нибудь в другой раз. :)
понедельник, 6 октября 2008 г.
Video Sitemap
Sitemap полезная технология, для указания поисковым системам где находится контент. Они конечно могут найти его и по ссылкам, но это дает возможность указать в первую очередь новые и изменившиеся страницы. Её поддерживают основные поисковики – Гугл, Яндекс, Яху, Лайв.
Этот протокол изначально планировался легко расширяемым (в кратце – это просто xml файл) и гугл уже добавил полезные дополнения. Это раширение протокола – Video Sitemaps. Оно полезно для разнообразных видеохостингов – указывает дополнительную информацию о видео, проигрывающихся на страницах. Гугл его использует при поиске по видео (http://video.google.com). Поэтому если у вас на сайте публикуется видео – настоятельно рекомендую обратить внимание. Также надеюсь, что Яндекс на своем поиске по видео http://video.yandex.ru тоже будет его использовать.
А теперь, по уже наметившейся традиции, хватит теории и немного практики. Конечно на .NET :)
В .NET 3.5 стало намного проще и изящнее создавать xml документы в коде с помощью LINQ to XML.
Вот небольшие выдержки из кода на FilmOnline.ru video sitemap сделан для трейлеров фильмов:
/// <summary>
/// For protocols details see https://www.google.com/webmasters/tools/docs/en/protocol.html
/// </summary>
public static readonly XNamespace sitemap =
"http://www.sitemaps.org/schemas/sitemap/0.9";
...
private static XDocument CreateSitemap(IEnumerable<MyPair<string, DateTimeOffset?>> locations,
Func<string, XElement, XElement> processor)
{
return new XDocument(
new XElement(sitemap + "urlset",
locations
.Where(loc => !string.IsNullOrEmpty(loc.First))
.Select(loc => processor(loc.First,
new XElement(sitemap + "url",
new XElement(sitemap + "loc", loc.First),
loc.Second.CoalesceEx(date =>
new XElement(sitemap + "lastmod",
date.Value.ToString("yyyy-MM-ddTHH:mm:ss%K")))
)))));
}
...
/// <summary>
/// For protocols details see http://www.google.com/support/webmasters/bin/answer.py?answer=80472&topic=10079
/// </summary>
public static readonly XNamespace video =
"http://www.google.com/schemas/sitemap-video/1.0";
...
element.Add(new XElement(video + "video",
new XElement(video + "content_loc", trailer.Data.AbsoluteUri),
new XElement(video + "title", trailer.Title),
trailer.Thumbnail.CoalesceEx(thumb =>
new XElement(video + "thumbnail_loc", thumb.AbsoluteUri))));
Пример результата можно посмотреть, например, здесь: http://filmonline.ru/Sitemap/External/Trailers/www.afisha.ru/movie/trailer/190429/.
пятница, 3 октября 2008 г.
Cooliris (Piclens) на своем сайте
Cooliris это прикольный плагин для всех основных браузеров для просмотра картинок и видео с веб-страниц. На словах звучит довольно пространно, так что лучше просто скачать и посмотреть.
Работает он на большинстве фото и видео хостинговых сайтов (YouTube, Flickr, Picasa Web, Яндекс.Фотки). Если в кратце – данные берет он из каналов RSS с раширением Media RSS (введеным Yahoo). Т.е. для того, что бы он заработал на собственном сайте надо просто cоздать такой RSS канал и сделать чтобы он автоматически находился (RSS Autodiscovery). Если более детально – то читаем расширенное руководство для разработчиков.
С помощью .NET 3.5 это сделать довольно просто – берем SyndicationFeed, заполняем его данными. К каждому элементу не забываем добавить необходимые расширения из Media RSS через свойство ElementExtensions.
Пример его работы можно наблюдать на FilmOnline.ru на страницах с описанием фильмов – там показываются трейлеры, постеры и кадры. Например, здесь (постеры) или здесь (трейлеры).
Кстати, обнаружилось недокументированное поведение. Когда на станице опубликовано несколько фидов (каналов), при нажатии кнопки плагина на тулбаре – он запускает всегда первый (хотя должен показывать все). Так что меняйте порядок подключения ваших фидов в нужном порядке. Например, опять же на FilmOnline, на всех страницах относящихся к фильму публикуются фиды и для фотографий, и для видео. Но на странице с трейлерами фид с видео на первом месте, а на странице постеров – фид с фотками.