Предположим, что у вас есть задача анализировать с помощью карты ряд показателей в разрезе административных районов Санкт-Петербурга.
Что вам потребуется из инструментов:
OBIEE 11g
Mapbuilder 11
Набор shape-файлов с геоданными
БД Oracle 11.2
Подготовительная работа
1. Устанавливаем Oracle BIEE 11g
2. Скачиваем mapbuilder
Так как далее мы будем загружать геоданные в кириллице – создайте командный скрипт запуска mapbuilder – mapbuilder.cmd – и поместите его рядом со скачанным jar-файлом:
java -Dfile.encoding=UTF8 -XX:MaxPermSize=512m -Xmx1024m -jar mapbuilder.jar
3. Сами геоданные – административные районы СПб – возьмем из opensource-источника OpenStreetMap
Выкачиваем набор shp-файлов по интересующему нас региону – в моем случае – Санкт-Петербургу.
Загрузка геоданных в БД Oracle
1. Создадим в БД нового пользователя OBIEE_MAPS
CREATE USER OBIEE_MAPS IDENTIFIED BY OBIEE_MAPS DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS; GRANT CONNECT TO OBIEE_MAPS; GRANT RESOURCE TO OBIEE_MAPS;
2. Откроем mapbuilder. Создадим в нем новое подключение к БД под созданным пользователем.
3. Импортируем в БД данные из shape-файла. (Имя создаваемой таблице следует давать без дефисов - STPETER_ADMIN_A)
Систему координат оставьте равной 8307 – именно в ней содержатся данные OpenStreetMap.
После импорта можно их посмотреть в mapbuilder.
4. Преобразуем импортированные данные в сферическую систему координат. (Спасибо Александру Рындину за наводку – без использования опции USE_SPHERICAL «не взлетало», геоданные расходились с картой-подложкой)
create table STPETER_ADMIN_A_3785 as select * from STPETER_ADMIN_A; update STPETER_ADMIN_A_3785 set geometry = sdo_cs.transform(geometry,'USE_SPHERICAL', 3785); commit; delete from user_sdo_geom_metadata where table_name = 'STPETER_ADMIN_A_3785'; insert into user_sdo_geom_metadata values('STPETER_ADMIN_A_3785', 'GEOMETRY', sdo_dim_array(sdo_dim_element('X', -20037508.3427, 20037508.3427, 0.05), sdo_dim_element('Y', -20037508.3427, 20037508.3427, 0.05)), 3785); -- create spatial indexes create index STPETER_ADMIN_A_3785_sidx on STPETER_ADMIN_A_3785(GEOMETRY) indextype is mdsys.spatial_index;
5. Теперь в предпросмотре mapbuilder видим более привычную (по google/yandex maps) картину.
6. Удалим из таблицы лишние данные, чтобы остались только административные районы.
delete from stpeter_admin_a_3785 t where nvl(t.admin_leve, -999) != 5 or t.name is null
Настроим mapviewer в поставке OBIEE 11g
Теперь необходимо настроить mapviewer – средство отображения геоданных на карте.
Так как mapviewer не работает напрямую с таблицами геоданных, потребуется еще ряд манипуляций в mapbuilder.
1. Создадим геометрическую тему.
Тема будет выглядеть так:
2. Создадим базовую карту
3. Создадим тайл
На данном этапе не будем настраивать уровни зуммирования и границы карты. Оставим так, как сгенерирует mapbuilder.
4. Зайдем в mapviewer - http://host:9704/mapviewer под администратором (weblogic)
5. Создадим постоянное подключение к нашей схеме OBIEE_MAPS
6. После перезагрузки мы видим созданное подключение и его карты.
7. Теперь создадим корректные значения границ карты и ее уровней детализации.
Откроем на редактирование строку user_sdo_cached_maps с созданным нами через mapbuilder тайлом.
Выгрузим XML с данными из столбца DEFINITION.
Заменим в нем соответствующие узлы:
<coordinate_system srid="3785" minX="-2.0037508E7" minY="-2.0037508E7" maxX="2.0037508E7" maxY="2.0037508E7"/>
И
<zoom_levels levels="20" min_scale="0.0" max_scale="0.0" min_tile_width="76.43702697753906" min_tile_height="4.00750166855785E7"> <zoom_level level="0" name="" description="" scale="0.0" tile_width="4.00750166855785E7" tile_height="4.00750166855785E7"/> <zoom_level level="1" name="" description="" scale="0.0" tile_width="2.0037508E7" tile_height="2.0037508E7"/> <zoom_level level="2" name="" description="" scale="0.0" tile_width="1.0018754E7" tile_height="1.0018754E7"/> <zoom_level level="3" name="" description="" scale="0.0" tile_width="5009377.0" tile_height="5009377.0"/> <zoom_level level="4" name="" description="" scale="0.0" tile_width="2504688.5" tile_height="2504688.5"/> <zoom_level level="5" name="" description="" scale="0.0" tile_width="1252344.25" tile_height="1252344.25"/> <zoom_level level="6" name="" description="" scale="0.0" tile_width="626172.125" tile_height="626172.125"/> <zoom_level level="7" name="" description="" scale="0.0" tile_width="313086.0625" tile_height="313086.0625"/> <zoom_level level="8" name="" description="" scale="0.0" tile_width="156543.03125" tile_height="156543.03125"/> <zoom_level level="9" name="" description="" scale="0.0" tile_width="78271.515625" tile_height="78271.515625"/> <zoom_level level="10" name="" description="" scale="0.0" tile_width="39135.7578125" tile_height="39135.7578125"/> <zoom_level level="11" name="" description="" scale="0.0" tile_width="19567.87890625" tile_height="19567.87890625"/> <zoom_level level="12" name="" description="" scale="0.0" tile_width="9783.939453125" tile_height="9783.939453125"/> <zoom_level level="13" name="" description="" scale="0.0" tile_width="4891.9697265625" tile_height="4891.9697265625"/> <zoom_level level="14" name="" description="" scale="0.0" tile_width="2445.98486328125" tile_height="2445.98486328125"/> <zoom_level level="15" name="" description="" scale="0.0" tile_width="1222.992431640625" tile_height="1222.992431640625"/> <zoom_level level="16" name="" description="" scale="0.0" tile_width="611.4962158203125" tile_height="611.4962158203125"/> <zoom_level level="17" name="" description="" scale="0.0" tile_width="305.74810791015625" tile_height="305.74810791015625"/> <zoom_level level="18" name="" description="" scale="0.0" tile_width="152.87405395507812" tile_height="152.87405395507812"/> <zoom_level level="19" name="" description="" scale="0.0" tile_width="76.43702697753906" tile_height="76.43702697753906"/> </zoom_levels>
Зачем все это – станет ясно позднее.
Затем загрузите в поле DEFINITION обновленный XML, сохраните изменения, в интерфейсе mapviewer обновите данные соединения OBIEE_MAPS.
Убедитесь, что теперь наш tile layer содержит уже 20 уровней детализации.
Настроим OBIEE для визуализации карт
Сразу оговорюсь, что в текущем релизе OBIEE есть небольшой баг, который не позволяет отобразить карты, если вы заходите в систему под русской локалью (или еще под некоторыми).
Проблема в том, что ряд javascript переменных, используемых для инициализации и отрисовки карт, может быть дробными числами.
И почему-то разделитель целой и дробной части в значениях этих переменных зависит от настроек локали.
А javascript не воспринимает число числом, если у него разделитель отличен от точки.
Лечится это просто – в файле
…Middleware/Oracle_BI1/bifoundation/web/display/localedefinitions.xml
Следует для используемой локали (“ru-ru”) установить свойство decimalSeparator равным точке.
1. Войдем в OBIEE под администратором.
Настроим слои и карты
2. Создадим в репозитории OBIEE простейшую модель для теста: таблицу измерений с ключом по имени района и таблицу фактов с одним показателем – например, суммарная задолженность абонентов района, показатель заполним случайными числами.
create table D_SPB_ADM_REGIONS as select distinct t.name from stpeter_admin_a_3785 t create table F_DEBT as select t.name, abs(dbms_random.random) as debt from D_SPB_ADM_REGIONS t
3. «Протянем» эти таблицы в репозитории OBIEE.
4. Вернемся к настроенным слоям и картам в BI.
Добавим привязку слоя к ключу таблицы D_SPB_ADM_REGIONS
Переименуем слой
Повторно зайдем в карту (нужно, чтобы подцепилась связь с SubjectArea через слой карты), переименуем ее.
5. Теперь можно создать простенький ансвер, содержащий отображение данных в табличном виде, а также на карте.
Отображение подложки OpenStreetMap
Согласитесь, мы избалованы картографическими сервисами, и не видеть какую-то подложку под карту нам непривычно.
Далее описывается как настроить OBIEE для автоматического отображения вместе с любой картой ансверов подложки от OpenStreetMap (напоминаю, что это opensource источник).
1. Найдите файл
…Middleware/Oracle_BI1/bifoundation/web/app/res/b_mozilla/views/map/obips.map.js
Файл этот «оптимизирован» для веб – удалены все лишние пробелы, символы перевода строки – читать его сложно. Как вариант, воспользуйтесь утилитой Polystyle.
Нас интересует в нем функция
obips.Map.Viewer.prototype.initTileLayer
в нее следует добавить изменения:
//jack carver start var osmMapConfig= { "mapTileLayer":"OSM_MERCATOR", "format":"PNG", "coordSys": { "srid":3785, "type":"PROJECTED", "distConvFactor":1.0, "minX":-2.0037508E7,"minY":-2.0037508E7, "maxX":2.0037508E7,"maxY":2.0037508E7 }, "zoomLevels": [ {"zoomLevel":0,"name":"","tileWidth":4.00750166855785E7,"tileHeight":4.00750166855785E7,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":1,"name":"","tileWidth":2.0037508E7,"tileHeight":2.0037508E7,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":2,"name":"","tileWidth":1.0018754E7,"tileHeight":1.0018754E7,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":3,"name":"","tileWidth":5009377.0,"tileHeight":5009377.0,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":4,"name":"","tileWidth":2504688.5,"tileHeight":2504688.5,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":5,"name":"","tileWidth":1252344.25,"tileHeight":1252344.25,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":6,"name":"","tileWidth":626172.125,"tileHeight":626172.125,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":7,"name":"","tileWidth":313086.0625,"tileHeight":313086.0625,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":8,"name":"","tileWidth":156543.03125,"tileHeight":156543.03125,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":9,"name":"","tileWidth":78271.515625,"tileHeight":78271.515625,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":10,"name":"","tileWidth":39135.7578125,"tileHeight":39135.7578125,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":11,"name":"","tileWidth":19567.87890625,"tileHeight":19567.87890625,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":12,"name":"","tileWidth":9783.939453125,"tileHeight":9783.939453125,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":13,"name":"","tileWidth":4891.9697265625,"tileHeight":4891.9697265625,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":14,"name":"","tileWidth":2445.98486328125,"tileHeight":2445.98486328125,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":15,"name":"","tileWidth":1222.992431640625,"tileHeight":1222.992431640625,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":16,"name":"","tileWidth":611.4962158203125,"tileHeight":611.4962158203125,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":17,"name":"","tileWidth":305.74810791015625,"tileHeight":305.74810791015625,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":18,"name":"","tileWidth":152.87405395507812,"tileHeight":152.87405395507812,"tileImageWidth":256,"tileImageHeight":256}, {"zoomLevel":19,"name":"","tileWidth":76.43702697753906,"tileHeight":76.43702697753906,"tileImageWidth":256,"tileImageHeight":256} ] }; function getOSMMapTileURL(tx, ty, tw, th, level) { var x = (tx-osmMapConfig.coordSys.minX)/osmMapConfig.zoomLevels[level].tileWidth ; var y = (osmMapConfig.coordSys.maxY-ty)/osmMapConfig.zoomLevels[level].tileHeight-1 ; // use mapnik rendered tiles return "http://tile.openstreetmap.org/"+(level)+"/"+x+"/"+y+".png"; // use osmarender instead //return "http://tah.openstreetmap.org/Tiles/tile/"+(level)+"/"+x+"/"+y+".png"; } //jack carver end obips.Map.Viewer.prototype.initTileLayer = function() { this.maptile = new MVMapTileLayer(this.model.getMapContext().getTileName()); this.mapview.addMapTileLayer(this.maptile, obips.Map.createCallBack(this, this.continueLoad)) //jack carver start var osmBasemap = new MVCustomMapTileLayer(osmMapConfig, getOSMMapTileURL); this.mapview.addMapTileLayer(osmBasemap); window.myMapView = this.mapview; //for future purpose – jack carver //jack carver end };
Измененный файл obips.map.js можно скачать здесь.
Оптимизировать ли его обратно – решать вам. Я предпочел пока оставить его в «разобранном» виде. Так как править его, возможно, придется часто.
2. Изменив файл недостаточно просто очистить кеш браузера. Измененный JS-не подхватится.
Потребуется очистить кеш Weblogic Server’а: остановите его, удалите папку …Middleware/user_projects/domains/bifoundation_domain/servers/bi_server1/tmp
(либо скопируйте в эту папку измененный файл obips.map.js; у меня это папка /u01/app/Middleware/user_projects/domains/bifoundation_domain/servers/bi_server1/tmp/_WL_user/analytics_11.1.1/7dezjl/war/res/b_mozilla/views/map ), запустите WLS.
3. Очистите кеш браузера, если еще не делали этого.
4. Посмотрите на созданный ранее ансвер с картой.
Вот так симпатично получилось (естественно, следует помнить, что для отображения тайлов от OSM вам нужен доступ в интернет).
Что за ошибка выскакивает при попытке выполнить:
ОтветитьУдалитьupdate STPETER_ADMIN_A_3785 set geometry = sdo_cs.transform(geometry,'USE_SPHERICAL', 3785);
*
ERROR at line 1:
ORA-06553: PLS-307: too many declarations of 'TRANSFORM' match this call
Андрей, наверняка, версия БД у вас не 11.2.
ОтветитьУдалить(кстати, в версии 11.2.0.2 появилась возможность обойтись без этой опции - http://www.oraclegis.com/blog/?p=2077).
Как вариант, высылайте мне дамп с вашей табличкой - я ее трансформирую и перешлю обратно. Либо попробуйте сами на тестовой БД 11.2
Да версия 10.0.2.4 Также вместо Oracle Spatial стоит Intermedia.
ОтветитьУдалитьПошел по немного другому пути как тут:http://sproke.blogspot.com/2009/03/howto-open-street-map-in-oracle.html#Loading OSM from PostgreSQL
Осталось пару вопросов. Если можете подскажите
1) Где находятся эти SRID и как это посмотреть
2) ПРобовали ли в качестве вебсервера чтото еще кроме Mapviewer. Боюсь он мне не по карману.
При попытке настройки mapviewer (п.6.) созданние подключения выдаёт:
ОтветитьУдалитьData source cannot be created : MAPVIEWER-00011: Ошибка при создании источника данных карт.
Аналогичная проблема была при подключении БД с примерами mvdemo, помог только ручной запуск скриптов mcsdefinition.sql и mvdemo.sql, после поднятия дампа mvdemo.dmp.
Подскажите, в чем может быть проблема?
Этот комментарий был удален автором.
ОтветитьУдалитьМожно ли как-нибудь подцепить OSM-стили для shp-файлов, которые импортируются в базу?
ОтветитьУдалитьТ.е например у меня есть SLD-файл стиля из geoserver могу ли я применить его к описанному вами способу?
Подскажите в пункте 4
ОтветитьУдалитькогда "Добавим привязку слоя к ключу таблицы D_SPB_ADM_REGIONS"
поле "Ключ слоя" пустой! В чем может быть причина?
На этапе 1. Создадим геометрическую тему.
УдалитьНужно в вкладке advance надо заполнить
Key column и info column
Карта есть, а раскраски нет, все белое, в чем может быть причина?
ОтветитьУдалитьПроверьте есть ли у пользователя ORACLE, через которого работает MapViewer, привилегия CREATE TYPE.
УдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьOracle Bi По-Русски: Biee 11G: Mapviewer + Openstreetmap >>>>> Download Now
ОтветитьУдалить>>>>> Download Full
Oracle Bi По-Русски: Biee 11G: Mapviewer + Openstreetmap >>>>> Download LINK
>>>>> Download Now
Oracle Bi По-Русски: Biee 11G: Mapviewer + Openstreetmap >>>>> Download Full
>>>>> Download LINK