Показаны сообщения с ярлыком maps. Показать все сообщения
Показаны сообщения с ярлыком maps. Показать все сообщения

четверг, 4 августа 2011 г.

В Уфе Яндекс запустит в небо дирижабль

4 августа интернет-компания «Яндекс» начинает съемку городских панорам с высоты птичьего полета. Съемка будет производиться с беспилотного дирижабля.
Как отмечают в компании, это крупнейший беспилотный радиоуправляемый дирижабль в России: его длина – 12 метров, объем – 57 кубических метров.
Первым городом, в которой запустят дирижабль станет Уфа.
Фотосъемка будет вестись с высоты 150-200 метров. На аппарате установлены пять специальных фотокамер, на которые попадут главные улицы и площади города, а также сад имени Салавата Юлаева.
Вскоре, все снимки мы сможем увидеть на сервисе «Яндекс.Карты».

среда, 3 августа 2011 г.

MVC. Поиск на карте средствами API Яндекс.Карт


Итак, у нас есть карта с кучей объектов, все работает, и все вроде бы прекрасно. Но объектов становится все больше, и ориентироваться в них все сложнее. Поэтому юзеру рано или поздно захочется воспользоваться хотя бы простеньким поиском. Вот и попробуем сделать простенький поиск по названию объекта. Для этого нам нужно окошко для ввода поискового слова, кнопка для запуска поиска и контейнер для списка найденных объектов (у нас это будет просто DropDownList). При выборе в списке найденных объектов какого-либо элемента на карте будет отображаться соответствующий балун. Все это будет сделано на чистом jQuery с использованием API YandexMaps.
Для начала создадим необходимые контролы (листинг 1).
Листинг 1 – Контролы для поиска
    <table>
        <tr>
            <td>
                @Html.Editor("findWord")
            </td>
            <td>
                <input type="button" value="Find" id="findButton" />
            </td>
        </tr>
        <tr>
            <td>
                @Html.DropDownList("ObjName", Enumerable.Empty<SelectListItem>())
            </td>
            <td>
            </td>
        </tr>
    </table>

Теперь пишем функцию поиска объектов по введенному слову (листинг 2).
Листинг 2 – jQuery – функция поиска
        // Функция для поиска объектов среди имеющихся на карте
        // по названию объекта и добавления их в список
        function getFindList() {
           
            // поисковая стркоа
            var searchName = document.getElementById('findWord').value.replace(new RegExp(' ', 'i'), '.+');

            // "регулярка" для поиска
            re = new RegExp(searchName, 'i');

            // произведем поиск
            var result = group["new"].filter(function (overlay) {

                var i = overlay.name.search(re);

                if (i != -1) {

                    return overlay.name;
                }
             });

            // ищем список
            var findChild = $('#ObjName');

            findChild.empty();

            // заполняем
            $.each(result, function (index, resultItem) {

                findChild.append($('<option/>', {

                    value: resultItem.name,

                    text: resultItem.name
                }));
            });
        };

Остановимся подробнее на этой функции. Сначала мы получаем наше искомое слово, попутно избавляясь от лишним пробелов в нем. Далее составляем регулярное выражение, по которому будет происходить поиск (подробнее ознакомиться с регулярными выражениями можно тут, ну и Google в помощь). Далее, используя полученную «регулярку», осуществляем поиск методом API Яндекс.Карт. В переменной result у нас будут объекты, названия которых удовлетворяет нашей поисковой строке. Далее уже знакомый код по добавлению найденных значений в выпадающий список. Осталось вызвать эту функцию при клике по кнопке поиска (листинг 3).
Листинг 3 – Вызов поиска при клике по кнопке
        $('#findButton').click(function () {

            getFindList();

        });

Мы получили список объектов, которые удовлетворяют поисковой строке (рисунок 1).

Рисунок 1 – Список найденных объектов

Идем дальше. Нам нужно снова осуществить поиск на карте, но теперь уже по найденным названиям объектов. И теперь совпадение имен должно быть стопроцентным, т.е. никаких регулярных выражений. И, кроме того, необходимо показывать соответствующий балун (листинг 4).
Листинг 4 – Отображение балуна найденного объекта
        // Функция для отображения объекта
        // из списка найденных
        function showObject() {

            var findChild = $('#ObjName');

            var searchName = findChild.val();

            var result = group["new"].filter(function (overlay) {
                return overlay.name == searchName; // Точное совпадение
            });

            if (result[0] != null) {
                result[0].openBalloon();
            }
        };

Думаю, тут все понятно. Осталось вызвать эту функцию при выборе элемента списка (листинг 5).
Листинг 5 – Отображение балуна объекта при выборе его в списке
        $('#ObjName').change(function () {

            showObject();

        });
Собственно, все! Удачи!


четверг, 28 июля 2011 г.

MVC - часть3. CRUD логика (Detail)


Итак, в прошлой статье мы получили список объектов карты. Возле каждого объекта у нас имеется ссылки, в том числе и «Details». Вот о ней и поговорим. Сама по себе страница с подробностями об объекте не так интересна, но у нас же карта, так давайте вместе с подробностями отобразим небольшую карту, где бы отображался этот самый объект.
Сперва пишем экшен контроллера (листинг 1), а затем генерируем представление (листинг 2).
Листинг 1 – Экшен контроллера
        [HttpGet]
        public ActionResult MapObject_Details(long id)
        {
            if (id != 0)
            {
                DataManager db = new DataManager();

                return View(db.GetMapObject(id));
            }
            else
            {
                return View();
            }
        }
Листинг 2 – Представление Details
<fieldset>
    <legend>Map</legend>

    <div class="display-label">ObjName</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjName)
    </div>

    <div class="display-label">ObjAddress</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjAddress)
    </div>

    <div class="display-label">ObjType</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjType_id)
    </div>

    <div class="display-label">Description</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Description)
    </div>

    <div class="display-label">Contact</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Contact)
    </div>

    <div class="display-label">Longitude</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Longitude)
    </div>

    <div class="display-label">Latitude</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Latitude)
    </div>

    <div class="display-label">ObjType_id</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjType_id)
    </div>

    <div class="display-label">Author</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Author)
    </div>

    <div class="display-label">CreateDate</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.CreateDate)
    </div>
</fieldset>

Дополним эту разметку еще одним полем – скрытым:
@Html.HiddenFor(model => model.MapObj_id)

В этом скрытом поле на нашей странице будет присутствовать идентификатор объекта. Зачем он нам? А мы по его значению будем на карту грузить его балун. Рассмотрим, как. Для начала сделаем метод нашего менеджера данных, который по идентификатору будет отдавать данные об объекте (листинг 3).
Листинг 3 – Получаем данные объекта по идентификатору
        public List<object> GetMapObjectById(long mapObjId)
        {
            List<object> list = new List<object>();

            Map item = GetMapObject(mapObjId);

            var data = new
            {
                Name = item.ObjName,
                Style = item.MapObjType.Style,
                Latitude = item.Latitude,  //широта
                Longitude = item.Longitude, //долгота
                Html = "<table class='info'>" +
                        "<tr><th>Название</th><td>" + item.ObjName + "</td></tr>" +
                        "<tr><th>Адрес</th><td>" + item.ObjAddress + "</td></tr>" +
                        "<tr><th>Описание</th><td>" + item.Description + "</td></tr>" +
                        "<tr><th>Контакты</th><td>" + item.Contact + "</td></tr>" +
                        "<tr><th>Оценка</th><td>" + ((item.MiddleRating != 0) ? item.MiddleRating.ToString() : "нет") + "</td></tr>" +
                        "<tr><th><a href='/Home/Comment/" + item.MapObj_id + "'>Отзывы</a></th><td></td></tr>" +
                        "</table>",      //код для балуна
            };

            list.Add(data);

            return list;
        }

Как видно, тут мы формируем код балуна, который позже загрузим в js-скрипте.
Теперь пишем экшен, который запакует это все дело в JSON (листинг 4).
Листинг 4 – Экшен, передающий данные в представление
        [HttpGet]
        public JsonResult ObjectDetails(long mapObjId)
        {
            DataManager db = new DataManager();

            return Json(db.GetMapObjectById(mapObjId), JsonRequestBehavior.AllowGet);
        }

Остался скрипт, который загрузит наш JSON на карту (листинг 5).
Листинг 5 – Скрипт отображения данных на карте
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=AAFDuU0BAAAAWmDlWgMAn8sg2dtfRwaCuNPYn0etp5qnk6QAAAAAAAAAAAAwqKOA3GzAs8EObkeouS3eI9xZMA=="
        type="text/javascript">
    </script>

    <script type="text/javascript" src="../../Scripts/jquery-1.5.1.min.js">
    </script>

    <script type="text/javascript" >
        var group = [];
        var map;

        $(document).ready(function () {
            // Найдем на странице html элемент в котором будет размещаться карта
            map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);

            map.setCenter(new YMaps.GeoPoint(55.975669, 54.732613), 10);

            // добавим контролы
            map.addControl(new YMaps.ToolBar());
            map.addControl(new YMaps.Zoom());
            map.addControl(new YMaps.TypeControl());
            map.enableScrollZoom();

            var searchControl = new YMaps.SearchControl({
                resultsPerPage: 2,  // Количество объектов на странице
                useMapBounds: 1     // Объекты, найденные в видимой области карты
                // будут показаны в начале списка
            });
            map.addControl(searchControl);

            getObject(document.getElementById('MapObj_id').value);
        });

        // объект по идентификатору
        function getObject(mapObjId) {

            $.getJSON("/Home/ObjectDetails", { mapObjId: mapObjId }, function (mapObj) {

                var s;

                group["new"] = new YMaps.GeoObjectCollection("default#");

                $.each(mapObj, function (i) {

                    // Создание стиля для значка метки
                    s = new YMaps.Style();
                    s.iconStyle = new YMaps.IconStyle();
                    s.iconStyle.href = this.Style;
                    s.iconStyle.size = new YMaps.Point(18, 18);
                    s.iconStyle.offset = new YMaps.Point(-9, -9);
                    s.balloonContentStyle = new YMaps.BalloonContentStyle(
                            new YMaps.Template("<div>$[description]</div>")
                    );

                    var point = new YMaps.GeoPoint(this.Longitude, this.Latitude);
                    var placemark = new YMaps.Placemark(point, { hasHint: 1, style: s });
                    placemark.name = this.Name;

                    //тут засовываем html
                    placemark.description = this.Html + "<br />";

                    group["new"].add(placemark);
                });

                map.addOverlay(group["new"]);
            });
        };

    </script>

В общем то, схема уже нам знакома, комментировать нечего.
Результат на рисунке 1.

Рисунок 1 – Подробности об объекте карты


четверг, 23 июня 2011 г.

MVC - часть2. Data Access Level


В прошлой статье мы сошлись на том, что получать данные в контроллере не  есть хорошо и правильно. И это так. С данными должна работать модель. Но обычно программисты выделяют еще один уровень, еще одну модель, которую будет использовать основная, - Data Access Level. То есть модель, которая непосредственно получает данные из БД, XML и других источников. И тут мы подходим к вопросу о технологии доступа к данным. Т.к. мы программируем в мире объектно-ориентированном, то и логичным было появление так называемых объектно-ориентированных технологий доступа к данным - object-relational mapping (ORM). Что это, какие виды и типы бывают, мы рассматривать не будем – оставляю это для самостоятельного изучения. В нашем же проекте мы будем использовать технологию ADO.NET Entity Framework (EF), являющейся ORM решением для .Net Framework от Microsoft.
Напомню, что у нас есть таблица в БД MS SQL Server с данными об объектах нашей карты (листинг 1).
Листинг 1 – Таблица объектов карты
CREATE TABLE [dbo].[Map] (
  [id] int IDENTITY(1, 1) NOT NULL,
  [ObjectName] nvarchar(128) COLLATE Cyrillic_General_CI_AS NULL,
  [ObjectAddress] nvarchar(256) COLLATE Cyrillic_General_CI_AS NULL,
  [Longitude] nvarchar(128) COLLATE Cyrillic_General_CI_AS NULL,
  [Latitude] nvarchar(128) COLLATE Cyrillic_General_CI_AS NULL,
  PRIMARY KEY CLUSTERED ([id])
)

Создадим Data Entity модель по этой таблице. Для это щелкаем правой кнопкой на папке Model нашего проекта, выбираем там Add – New Item, видим диалоговое окно как на рисунке 1.

                            Рисунок 1 – Добавление нового элемента в проект

В этом диалоге выбираем раздел Data – ADO.NET Entity Data Model, называем нашу модель (например, MapDataModel). Далее студия запускает визард, который помогает нам правильно сформировать модель. Идем по порядку: Choose Model Contents – Generate from database, Choose Your Data Connection – вносите настройки коннекта к вашей БД, Choose Your Database Objects – Tables (Map). Все, готово! Через пару секунд студия сгенерирует нам модель доступа к данным (рисунок 2).
Рисунок 2 – Модель данных

У нас данные хранятся крайне просто. Если не сказать примитивно. Если же данные образуют сложную систему с внешними ключами и прочим, то студия это все поймет и сгенерирует соответствующее количество классов с соответствующими связями. Если мы заглянем в файл MapDataModel.Designer.cs, то увидим содержимое рисунка 3.
Рисунок 3 – Классы, описывающие данные

Теперь как с этим работать. Давайте создадим модель DataManager (Model – Add –Class - DataManager). Создадим конструктор (листинг 2).
Листинг 2 – Конструктор DataManager
        private ProjectEntities _db;

        public DataManager()
        {
            _db = new ProjectEntities();
        }

Тут все понятно – мы создаем соединение к нашей БД, чтоб через него брать данные. Далее нам нужно сформировать лист, который будет отдаваться клиенту (листинг 3).
Листинг 3 – Формирование списка объектов для карты
        public List<object> GetListObjectMap()
        {
            List<object> list = new List<object>();

            foreach (Map item in _db.Map)
            {
                var data = new
                {
                    Name = item.ObjectName,
                    Latitude = item.Latitude,   //широта
                    Longitude = item.Longitude, //долгота
                    Html = item.ObjectAddress,
                };
                list.Add(data);
            }
            return list;
        }

Тут тоже понятно – каждую запись из таблицы БД в цикле мы добавляем в список.
Теперь идем в контроллер и очищаем метод ObjectToMap(). Создадим в нем экземпляр нашего DataManager и сформированный лист отдадим клиенту (листинг 4).
Листинг 4 – Обновленный метод контроллера ObjectToMap()
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult ObjectToMap()
        {
            DataManager dm = new DataManager();

            return Json(dm.GetListObjectMap(), JsonRequestBehavior.AllowGet);
        }

Рисунок 4 – Результат работы

Просто? Вот так красиво и удобно.
Для лучшего понимания того, как и что делать, рекомендую изучать видеоподкасты на сайте . В них с комментариями описываются основные приемы работы от самых простых к сложным.
В следующей статье мы рассмотрим, как можно редактировать объекты нашей карты.