Наверняка, многие из читателей этого блога так или иначе использовали функциональность аналитики "на карте".
Причем, скорее всего, применяли отображение показателей по определенным точкам. Например, объем реализации по магазинам… С выделением цветом или изменением размера точки-"пузырька" в зависимости от значения показателя.
Для этого нужно не так уж много (не буду вдаваться во все детали) – основная сложность тут лишь в корректных значениях координат ваших точек.
Получить эти координаты можно различными способами: GPS-приборами, поиском по какому-нибудь картографическому сервису нужного дома (Google Map это отлично умеет) и т.д.
Но все это требует времени и сил.
А что если задача усложняется нерегулярностью появления новых гео-точек для бизнес-анализа?
Например, каждый запуск ETL-процедур может привести к появлению новых локаций с пустыми координатами в DWH,
либо как в моем случае – необходимо обеспечить возможность создания пользователем новых гео-локаций (магазины-конкуренты), а также возможность позиционирования этих точек на карте.
Я эту задачу решил следующим образом:
В специально настроенном анализе BI выводится информация с уникальным идентификатором магазина, его названием, его координатами (широта и долгота, пустые поначалу).
Рядом с табличной частью анализа выводится представление "Карта" без каких-либо слоев отображения.
В свойствах столбца с названием магазина на вкладке "Взаимодействие" настроен вызов ActionLink с типом BrowserScript, суть которого в том, чтобы при вызове отобразить на текущей активной карте "красную точку" с возможностью ее перемещения мышкой (очевидно, что "красная точка" - вырожденный инструмент mapviewer.redline – должна отображаться в текущем центре карты, если координаты пустые, либо в месте, соответствующем имеющимся координатам магазина).
Также в анализ я добавил фиктивный столбец-константу со значением "Сохранить", на который тоже назначен ActionScript, суть которого в передаче ajax-запроса на сервер с уникальным кодом редактируемого магазина и его измененными координатами.
Ясно, что основной интерес как раз представляет содержимое файла USERSCRIPTS.js, обеспечивающее указанную функциональность.
Напоминаю, что в Weblogic применяется хитрая стратегия кеширования, поэтому искать и править ВАШ файл UserScripts.js нужно в недрах WLS.
У меня на рабочем сервере искомый файл находится в папке
c:\Middleware117\user_projects\domains\bifoundation_domain\servers\AdminServer\tmp\_WL_user\analytics_11.1.1\silp1v\war\res\b_mozilla\actions\UserScripts.js
Вот его содержимое:
USERSCRIPT = function () {}; USERSCRIPT.parameter = function (b, a, c) { this.name = b; this.prompt = a; this.value = c }; USERSCRIPT.startEditLocation = function (d) { var locationKey = d.locationKey; var locationName = d.locationName; var coordX = parseFloat(d.coordX); var coordY = parseFloat(d.coordY); //var mapview = window.myMapView; var mapview = obips.Map.getMapView(obips.Map.Factory.getSingleton().currentMapID); var redline = window.myRedline; if (redline != null) redline.clear(); redline = new MVRedlineTool(null, "MDSYS.C.RED"); redline.setAutoClose(false); redline.setControlPanelVisible(false); redline.setEditingMode({ deletePoint: false, dragPoint: true, deleteLine: false, dragLine: false }); window.myRedline = redline; mapview.addRedLineTool(redline); redline.init(1); var centerPoint; if (coordX != null && coordX != 0) { centerPoint = MVSdoGeometry.createPoint(coordX, coordY, 8307); centerPoint = mapview.transformGeom(centerPoint, 3785); } else { centerPoint = mapview.getCenter(); } mapview.setCenter(centerPoint); redline.addVertex(0, centerPoint.getPointX(), centerPoint.getPointY()); window.myLocationKey = locationKey; var md1 = window.myMapDecoration; if (md1 != null) { mapview.removeMapDecoration(md1); } md1 = new MVMapDecoration(locationName, 0.1, 0.1, 200, 20); mapview.addMapDecoration(md1); window.myMapDecoration = md1; }; USERSCRIPT.startEditLocation.publish = { parameters: [new USERSCRIPT.parameter("locationKey", "Enter value for locationKey", ""), new USERSCRIPT.parameter("locationName", "Enter value for locationName", ""), new USERSCRIPT.parameter("coordX", "Enter value for coordX", ""), new USERSCRIPT.parameter("coordY", "Enter value for coordY", "") ] }; USERSCRIPT.endEditLocation = function (d) { var locationKey = window.myLocationKey; if (locationKey == null) return; var redline = window.myRedline; var mapview = window.myMapView; if (redline == null) return; if (redline != null) { var coords = redline.getOrdinates().toString(); var coordsArray = coords.split(","); var currentPoint = MVSdoGeometry.createPoint(parseFloat(coordsArray[0]), parseFloat(coordsArray[1]), 3785); currentPoint = mapview.transformGeom(currentPoint, 8307); var url = "http://" + document.location.host + "/analyticsTools/saveLocationCoord.jsp?"; url += "locationKey=" + encodeURIComponent(locationKey); url += "&x=" + currentPoint.getPointX() + "&y=" + currentPoint.getPointY(); var xmlHttp; try { // Firefox, Opera 8.0 + , Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Your browser does not support AJAX!"); return false; } } } xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4) { window.status = "Done"; document.body.style.cursor = "default"; var h = xmlHttp.responseText; var d = obips.MessageDialog.TITLE_IMAGE_INFO; var c = new obips.MessageDialog.Model(null, h, null, d); var e = new obips.MessageDialog.Viewer(c, obips.FloatingWindow.Manager.getSingleton()); e.footerDiv.style.textAlign = "center"; RefreshPage(); } } window.status = "Please wait..."; document.body.style.cursor = "wait"; xmlHttp.open("POST", url, true); xmlHttp.send(null); } var md1 = window.myMapDecoration; if (md1 != null) { mapview.removeMapDecoration(md1); } }; USERSCRIPT.endEditLocation.publish = { parameters: [new USERSCRIPT.parameter("locationKey", "Enter value for locationKey", "")] };
И наконец, код jsp-страницы saveLocationCoord.jsp, обеспечивающей прием ajax-запросов на сохранение координат и их запись в БД
(Я создал и задеплоил в WLS дополнительное веб-приложение analyticsTools, расположенное в каталоге сервера c:\Middleware117\Oracle_BI1\bifoundation\jee\analyticsTools.war
В корне которого и создал новую jsp-страницу)
<%@ page contentType="text/html; charset=UTF-8"%> <%@ page import="java.io.*"%> <%@ page import="java.net.*"%> <%@ page import="java.sql.*"%> <%@ page import="javax.sql.*"%> <%@ page import="java.util.*"%> <%@ page import="javax.naming.*"%> <% try{ String locationKey = URLEncoder.encode(request.getParameter("locationKey"), "UTF-8"); String preCoordX = request.getParameter("x"); String preCoordY = request.getParameter("y"); double coordX = Double.parseDouble(preCoordX); double coordY = Double.parseDouble(preCoordY); Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup ("jdbc/DWH_datasource"); Connection conn = ds.getConnection(); String updateQuery = "update DWI_RIVAL_STORE_LCTN set longitude = ? , latitude = ? where location_key = ? "; PreparedStatement updateStatement = conn.prepareStatement(updateQuery); updateStatement.setDouble(1, coordX); updateStatement.setDouble(2, coordY); updateStatement.setString(3, locationKey); updateStatement.executeUpdate(); conn.commit(); updateStatement.close(); updateStatement = null; out.write("Success! Refresh the page"); } catch (Exception ex) { out.write(ex.toString()); } %>
Очевидно, что для корректной работы JSP-кода необходимо наличие JNDI-источника данных с именем jdbc/DWH_datasource
Вот и все!
Прикольная идея!
ОтветитьУдалитьПобуду буквоедом, сам сейчас с этим копаюсь:
“(Google Map это отлично умеет)”
— плохой совет, потому что:
The Geocoding API may only be used in conjunction with a Google map; geocoding results without displaying them on a map is prohibited. For complete details on allowed usage, consult the Maps API Terms of Service License Restrictions.
https://developers.google.com/maps/documentation/geocoding/#Limits
Согласен с Вами. Если строго следовать букве закона - то так делать нельзя!
ОтветитьУдалитьНо обычно именно так и поступают: открывают GMaps, тыкают мышкой в точку и выбирают в контекстном меню "Что тут находится" - в поле поиска появляются координаты; их затем и используют.