Наверняка, многие из читателей этого блога так или иначе использовали функциональность аналитики "на карте".
Причем, скорее всего, применяли отображение показателей по определенным точкам. Например, объем реализации по магазинам… С выделением цветом или изменением размера точки-"пузырька" в зависимости от значения показателя.

Для этого нужно не так уж много (не буду вдаваться во все детали) – основная сложность тут лишь в корректных значениях координат ваших точек.
Получить эти координаты можно различными способами: 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, тыкают мышкой в точку и выбирают в контекстном меню "Что тут находится" - в поле поиска появляются координаты; их затем и используют.