123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- /* vim: set expandtab sw=4 ts=4 sts=4: */
- /**
- * @fileoverview functions used for visualizing GIS data
- *
- * @requires jquery
- * @requires vendor/jquery/jquery.svg.js
- * @requires vendor/jquery/jquery.mousewheel.js
- * @requires vendor/jquery/jquery.event.drag-2.2.js
- */
- // Constants
- var zoomFactor = 1.5;
- var defaultX = 0;
- var defaultY = 0;
- // Variables
- var x = 0;
- var y = 0;
- var scale = 1;
- var svg;
- /**
- * Zooms and pans the visualization.
- */
- function zoomAndPan () {
- var g = svg.getElementById('groupPanel');
- if (!g) {
- return;
- }
- g.setAttribute('transform', 'translate(' + x + ', ' + y + ') scale(' + scale + ')');
- var id;
- var circle;
- $('circle.vector').each(function () {
- id = $(this).attr('id');
- circle = svg.getElementById(id);
- $(svg).change(circle, {
- r : (3 / scale),
- 'stroke-width' : (2 / scale)
- });
- });
- var line;
- $('polyline.vector').each(function () {
- id = $(this).attr('id');
- line = svg.getElementById(id);
- $(svg).change(line, {
- 'stroke-width' : (2 / scale)
- });
- });
- var polygon;
- $('path.vector').each(function () {
- id = $(this).attr('id');
- polygon = svg.getElementById(id);
- $(svg).change(polygon, {
- 'stroke-width' : (0.5 / scale)
- });
- });
- }
- /**
- * Initially loads either SVG or OSM visualization based on the choice.
- */
- function selectVisualization () {
- if ($('#choice').prop('checked') !== true) {
- $('#openlayersmap').hide();
- } else {
- $('#placeholder').hide();
- }
- }
- /**
- * Adds necessary styles to the div that coontains the openStreetMap.
- */
- function styleOSM () {
- var $placeholder = $('#placeholder');
- var cssObj = {
- 'border' : '1px solid #aaa',
- 'width' : $placeholder.width(),
- 'height' : $placeholder.height(),
- 'float' : 'right'
- };
- $('#openlayersmap').css(cssObj);
- }
- /**
- * Loads the SVG element and make a reference to it.
- */
- function loadSVG () {
- var $placeholder = $('#placeholder');
- $placeholder.svg({
- onLoad: function (svg_ref) {
- svg = svg_ref;
- }
- });
- // Removes the second SVG element unnecessarily added due to the above command
- $placeholder.find('svg:nth-child(2)').remove();
- }
- /**
- * Adds controllers for zooming and panning.
- */
- function addZoomPanControllers () {
- var $placeholder = $('#placeholder');
- if ($('#placeholder').find('svg').length > 0) {
- var pmaThemeImage = $('#pmaThemeImage').val();
- // add panning arrows
- $('<img class="button" id="left_arrow" src="' + pmaThemeImage + 'west-mini.png">').appendTo($placeholder);
- $('<img class="button" id="right_arrow" src="' + pmaThemeImage + 'east-mini.png">').appendTo($placeholder);
- $('<img class="button" id="up_arrow" src="' + pmaThemeImage + 'north-mini.png">').appendTo($placeholder);
- $('<img class="button" id="down_arrow" src="' + pmaThemeImage + 'south-mini.png">').appendTo($placeholder);
- // add zooming controls
- $('<img class="button" id="zoom_in" src="' + pmaThemeImage + 'zoom-plus-mini.png">').appendTo($placeholder);
- $('<img class="button" id="zoom_world" src="' + pmaThemeImage + 'zoom-world-mini.png">').appendTo($placeholder);
- $('<img class="button" id="zoom_out" src="' + pmaThemeImage + 'zoom-minus-mini.png">').appendTo($placeholder);
- }
- }
- /**
- * Resizes the GIS visualization to fit into the space available.
- */
- function resizeGISVisualization () {
- var $placeholder = $('#placeholder');
- var old_width = $placeholder.width();
- var visWidth = $('#div_view_options').width() - 48;
- // Assign new value for width
- $placeholder.width(visWidth);
- $('svg').attr('width', visWidth);
- // Assign the offset created due to resizing to defaultX and center the svg.
- defaultX = (visWidth - old_width) / 2;
- x = defaultX;
- y = 0;
- scale = 1;
- }
- /**
- * Initialize the GIS visualization.
- */
- function initGISVisualization () {
- // Loads either SVG or OSM visualization based on the choice
- selectVisualization();
- // Resizes the GIS visualization to fit into the space available
- resizeGISVisualization();
- if (typeof OpenLayers !== 'undefined') {
- // Configure OpenLayers
- OpenLayers._getScriptLocation = function () {
- return './js/vendor/openlayers/';
- };
- // Adds necessary styles to the div that coontains the openStreetMap
- styleOSM();
- // Draws openStreetMap with openLayers
- drawOpenLayers();
- }
- // Loads the SVG element and make a reference to it
- loadSVG();
- // Adds controllers for zooming and panning
- addZoomPanControllers();
- zoomAndPan();
- }
- function getRelativeCoords (e) {
- var position = $('#placeholder').offset();
- return {
- x : e.pageX - position.left,
- y : e.pageY - position.top
- };
- }
- /**
- * Ajax handlers for GIS visualization page
- *
- * Actions Ajaxified here:
- *
- * Zooming in and zooming out on mousewheel movement.
- * Panning the visualization on dragging.
- * Zooming in on double clicking.
- * Zooming out on clicking the zoom out button.
- * Panning on clicking the arrow buttons.
- * Displaying tooltips for GIS objects.
- */
- /**
- * Unbind all event handlers before tearing down a page
- */
- AJAX.registerTeardown('tbl_gis_visualization.js', function () {
- $(document).off('click', '#choice');
- $(document).off('mousewheel', '#placeholder');
- $(document).off('dragstart', 'svg');
- $(document).off('mouseup', 'svg');
- $(document).off('drag', 'svg');
- $(document).off('dblclick', '#placeholder');
- $(document).off('click', '#zoom_in');
- $(document).off('click', '#zoom_world');
- $(document).off('click', '#zoom_out');
- $(document).off('click', '#left_arrow');
- $(document).off('click', '#right_arrow');
- $(document).off('click', '#up_arrow');
- $(document).off('click', '#down_arrow');
- $('.vector').off('mousemove').off('mouseout');
- });
- AJAX.registerOnload('tbl_gis_visualization.js', function () {
- // If we are in GIS visualization, initialize it
- if ($('#gis_div').length > 0) {
- initGISVisualization();
- }
- if (typeof OpenLayers === 'undefined') {
- $('#choice, #labelChoice').hide();
- }
- $(document).on('click', '#choice', function () {
- if ($(this).prop('checked') === false) {
- $('#placeholder').show();
- $('#openlayersmap').hide();
- } else {
- $('#placeholder').hide();
- $('#openlayersmap').show();
- }
- });
- $(document).on('mousewheel', '#placeholder', function (event, delta) {
- event.preventDefault();
- var relCoords = getRelativeCoords(event);
- if (delta > 0) {
- // zoom in
- scale *= zoomFactor;
- // zooming in keeping the position under mouse pointer unmoved.
- x = relCoords.x - (relCoords.x - x) * zoomFactor;
- y = relCoords.y - (relCoords.y - y) * zoomFactor;
- zoomAndPan();
- } else {
- // zoom out
- scale /= zoomFactor;
- // zooming out keeping the position under mouse pointer unmoved.
- x = relCoords.x - (relCoords.x - x) / zoomFactor;
- y = relCoords.y - (relCoords.y - y) / zoomFactor;
- zoomAndPan();
- }
- return true;
- });
- var dragX = 0;
- var dragY = 0;
- $(document).on('dragstart', 'svg', function (event, dd) {
- $('#placeholder').addClass('placeholderDrag');
- dragX = Math.round(dd.offsetX);
- dragY = Math.round(dd.offsetY);
- });
- $(document).on('mouseup', 'svg', function (event) {
- $('#placeholder').removeClass('placeholderDrag');
- });
- $(document).on('drag', 'svg', function (event, dd) {
- var newX = Math.round(dd.offsetX);
- x += newX - dragX;
- dragX = newX;
- var newY = Math.round(dd.offsetY);
- y += newY - dragY;
- dragY = newY;
- zoomAndPan();
- });
- $(document).on('dblclick', '#placeholder', function (event) {
- scale *= zoomFactor;
- // zooming in keeping the position under mouse pointer unmoved.
- var relCoords = getRelativeCoords(event);
- x = relCoords.x - (relCoords.x - x) * zoomFactor;
- y = relCoords.y - (relCoords.y - y) * zoomFactor;
- zoomAndPan();
- });
- $(document).on('click', '#zoom_in', function (e) {
- e.preventDefault();
- // zoom in
- scale *= zoomFactor;
- var $placeholder = $('#placeholder').find('svg');
- width = $placeholder.attr('width');
- height = $placeholder.attr('height');
- // zooming in keeping the center unmoved.
- x = width / 2 - (width / 2 - x) * zoomFactor;
- y = height / 2 - (height / 2 - y) * zoomFactor;
- zoomAndPan();
- });
- $(document).on('click', '#zoom_world', function (e) {
- e.preventDefault();
- scale = 1;
- x = defaultX;
- y = defaultY;
- zoomAndPan();
- });
- $(document).on('click', '#zoom_out', function (e) {
- e.preventDefault();
- // zoom out
- scale /= zoomFactor;
- var $placeholder = $('#placeholder').find('svg');
- width = $placeholder.attr('width');
- height = $placeholder.attr('height');
- // zooming out keeping the center unmoved.
- x = width / 2 - (width / 2 - x) / zoomFactor;
- y = height / 2 - (height / 2 - y) / zoomFactor;
- zoomAndPan();
- });
- $(document).on('click', '#left_arrow', function (e) {
- e.preventDefault();
- x += 100;
- zoomAndPan();
- });
- $(document).on('click', '#right_arrow', function (e) {
- e.preventDefault();
- x -= 100;
- zoomAndPan();
- });
- $(document).on('click', '#up_arrow', function (e) {
- e.preventDefault();
- y += 100;
- zoomAndPan();
- });
- $(document).on('click', '#down_arrow', function (e) {
- e.preventDefault();
- y -= 100;
- zoomAndPan();
- });
- /**
- * Detect the mousemove event and show tooltips.
- */
- $('.vector').on('mousemove', function (event) {
- var contents = $.trim(escapeHtml($(this).attr('name')));
- $('#tooltip').remove();
- if (contents !== '') {
- $('<div id="tooltip">' + contents + '</div>').css({
- position : 'absolute',
- top : event.pageY + 10,
- left : event.pageX + 10,
- border : '1px solid #fdd',
- padding : '2px',
- 'background-color' : '#fee',
- opacity : 0.90
- }).appendTo('body').fadeIn(200);
- }
- });
- /**
- * Detect the mouseout event and hide tooltips.
- */
- $('.vector').on('mouseout', function (event) {
- $('#tooltip').remove();
- });
- });
|