Mercurial > hg > LGMap
view geotemco/js/Map/PlacenameTags.js @ 23:d864c58ae667
For avoiding ssl warning, changing the link, mapquest.com, from http to https
author | Calvin Yeh <cyeh@mpipw-berlin.mpg.com> |
---|---|
date | Wed, 29 Mar 2017 07:04:44 +0200 |
parents | 57bde4830927 |
children |
line wrap: on
line source
/* * PlacenameTags.js * * Copyright (c) 2012, Stefan Jänicke. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ /** * @class PlacenameTags * place labels computation for circles * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) * @release 1.0 * @release date: 2012-07-27 * @version date: 2012-07-27 */ function PlacenameTags(circle, map) { this.circle = circle; this.map = map; this.placeLabels this.selectedLabel this.allLabel this.othersLabel this.unknownLabel this.calculate = function() { this.calculateLabels(); this.calculatePlacenameTags(); } this.calculateLabels = function() { var elements = this.circle.elements; var k = this.circle.search; var weight = 0; var labels = []; var levelOfDetail = 0; if (this.map.options.placenameTagsStyle === 'zoom') levelOfDetail = this.map.getLevelOfDetail(); if (this.map.options.placenameTagsStyle === 'value'){ //find max level that _all_ elements have a value for var maxLevel; for (var i = 0; i < elements.length; i++) { var level = elements[i].placeDetails[this.map.options.mapIndex].length-1; if (typeof maxLevel === "undefined") maxLevel = level; if (maxLevel > level) maxLevel = level; //smallest level anyway, no need to look any further if (level == 0) break; } //search for highest level where the values differ for (levelOfDetail = 0; levelOfDetail < maxLevel; levelOfDetail++){ var differenceFound = false; for (var i = 0; i < (elements.length-1); i++) { if ( elements[i].getPlace(this.map.options.mapIndex, levelOfDetail) !== elements[i+1].getPlace(this.map.options.mapIndex, levelOfDetail)) differenceFound = true; } if (differenceFound === true) break; } } for (var i = 0; i < elements.length; i++) { weight += elements[i].weight; var found = false; var label = elements[i].getPlace(this.map.options.mapIndex, levelOfDetail); if (label == "") { label = "unknown"; } for (var j = 0; j < labels.length; j++) { if (labels[j].place == label) { labels[j].elements.push(elements[i]); labels[j].weight += elements[i].weight; found = true; break; } } if (!found) { labels.push({ id : elements[i].name, place : label, elements : new Array(elements[i]), weight : elements[i].weight, index : k }); } } var sortBySize = function(label1, label2) { if (label1.weight > label2.weight) { return -1; } return 1; } labels.sort(sortBySize); if (map.options.maxPlaceLabels) { var ml = map.options.maxPlaceLabels; if (ml == 1) { labels = []; labels.push({ place : "all", elements : elements, weight : weight, index : k }); } if (ml == 2) { ml++; } if (ml > 2 && labels.length + 1 > ml) { var c = []; var w = 0; for (var i = ml - 2; i < labels.length; i++) { c = c.concat(labels[i].elements); w += labels[i].weight; } labels = labels.slice(0, ml - 2); labels.push({ place : "others", elements : c, weight : w, index : k }); } } if (labels.length > 1) { labels.push({ place : "all", elements : elements, weight : weight, index : k }); } this.placeLabels = labels; }; this.calculatePlacenameTags = function() { var cloud = this; var c = GeoTemConfig.getColor(this.circle.search); if( map.options.useGraphics ){ c = map.config.getGraphic(this.circle.search).color; } var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; var color1 = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; var allStyles = "", hoverStyle = "", highlightStyle = "", selectedStyle = "", unselectedStyle = ""; if (GeoTemConfig.ie) { highlightStyle += map.options.ieHighlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; hoverStyle += map.options.ieHoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; selectedStyle += map.options.ieSelectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; unselectedStyle += map.options.ieUnselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; } else { highlightStyle += map.options.highlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; hoverStyle += map.options.hoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; selectedStyle += map.options.selectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; unselectedStyle += map.options.unselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; } var clickFunction = function(label) { label.div.onclick = function() { cloud.changeLabelSelection(label); } } var maxLabelSize = this.count for (var i = 0; i < this.placeLabels.length; i++) { var l = this.placeLabels[i]; l.selected = false; var div = document.createElement("div"); div.setAttribute('class', 'tagCloudItem'); var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; if (l.place == "all") { fontSize = 1; } div.style.fontSize = fontSize + "em"; l.allStyle = allStyles + "font-size: " + fontSize + "em;"; l.selectedStyle = selectedStyle; l.unselectedStyle = unselectedStyle; l.highlightStyle = highlightStyle; l.hoverStyle = hoverStyle; div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; l.div = div; clickFunction(l); } if (map.options.labelGrid) { this.showPlacelabels(); } else { for (var i = 0; i < this.placeLabels.length; i++) { this.placeLabels[i].div.setAttribute('style', this.placeLabels[i].allStyle + "" + this.placeLabels[i].highlightStyle); } } }; this.selectLabel = function(label) { if ( typeof label == 'undefined') { label = this.placeLabels[this.placeLabels.length - 1]; } if (this.map.popup) { this.map.popup.showLabelContent(label); } this.selectedLabel = label; this.selectedLabel.div.setAttribute('style', this.selectedLabel.allStyle + "" + this.selectedLabel.selectedStyle); this.map.mapLabelSelection(label); }; // changes selection between labels (click, hover) this.changeLabelSelection = function(label) { if (this.selectedLabel == label) { return; } if ( typeof this.selectedLabel != 'undefined') { this.selectedLabel.div.setAttribute('style', this.selectedLabel.allStyle + "" + this.selectedLabel.unselectedStyle); } this.selectLabel(label); }; this.showPlacelabels = function() { this.leftDiv = document.createElement("div"); this.leftDiv.setAttribute('class', 'tagCloudDiv'); this.map.gui.mapWindow.appendChild(this.leftDiv); this.rightDiv = document.createElement("div"); this.rightDiv.setAttribute('class', 'tagCloudDiv'); this.map.gui.mapWindow.appendChild(this.rightDiv); for (var i = 0; i < this.placeLabels.length; i++) { if (i % 2 == 0) { this.leftDiv.appendChild(this.placeLabels[i].div); } else { this.rightDiv.appendChild(this.placeLabels[i].div); } this.placeLabels[i].div.setAttribute('style', this.placeLabels[i].allStyle + "" + this.placeLabels[i].highlightStyle); } this.placeTagCloud(); }; this.placeTagCloud = function() { var lonlat = new OpenLayers.LonLat(this.circle.feature.geometry.x, this.circle.feature.geometry.y); var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); var radius = this.circle.feature.style.pointRadius; var lw = this.leftDiv.offsetWidth; var rw = this.rightDiv.offsetWidth; this.leftDiv.style.left = (pixel.x - radius - lw - 5) + "px"; this.rightDiv.style.left = (pixel.x + radius + 5) + "px"; var lh = this.leftDiv.offsetHeight; var rh = this.rightDiv.offsetHeight; var lt = pixel.y - lh / 2; var rt = pixel.y - rh / 2; this.leftDiv.style.top = lt + "px"; this.rightDiv.style.top = rt + "px"; }; this.remove = function() { $(this.leftDiv).remove(); $(this.rightDiv).remove(); }; }; function PackPlacenameTags(circle, map) { this.circle = circle; this.map = map; this.placeLabels this.selectedLabel this.allLabel this.othersLabel this.unknownLabel this.calculate = function() { this.calculateLabels(); this.calculatePlacenameTags(); } this.getLabelList = function(circle) { var elements = circle.elements; var k = circle.search; var weight = 0; var labels = []; var levelOfDetail = this.map.getLevelOfDetail(); for (var i = 0; i < elements.length; i++) { weight += elements[i].weight; var found = false; var label = elements[i].getPlace(this.map.options.mapIndex, levelOfDetail); if (label == "") { label = "unknown"; } for (var j = 0; j < labels.length; j++) { if (labels[j].place == label) { labels[j].elements.push(elements[i]); labels[j].weight += elements[i].weight; found = true; break; } } if (!found) { labels.push({ id : elements[i].name, place : label, elements : new Array(elements[i]), weight : elements[i].weight, index : k }); } } var sortBySize = function(label1, label2) { if (label1.weight > label2.weight) { return -1; } return 1; } labels.sort(sortBySize); var droppedLabels = []; if (map.options.maxPlaceLabels) { var ml = map.options.maxPlaceLabels; if (ml == 1) { labels = []; labels.push({ place : "all", elements : elements, weight : weight, index : k }); } if (ml == 2) { ml++; } if (ml > 2 && labels.length + 1 > ml) { var c = []; var w = 0; for (var i = ml - 2; i < labels.length; i++) { c = c.concat(labels[i].elements); w += labels[i].weight; droppedLabels.push(labels[i]); } labels = labels.slice(0, ml - 2); var ol = { place : "others", elements : c, weight : w, index : k }; labels.push(ol); this.othersLabels.push(ol); } } if (labels.length > 1) { labels.push({ place : "all", elements : elements, weight : weight, index : k }); } this.placeLabels.push(labels); this.droppedLabels.push(droppedLabels); }; this.calculateLabels = function() { var circles = this.circle.circles; this.placeLabels = []; this.droppedLabels = []; this.othersLabels = []; for (var i = 0; i < circles.length; i++) { this.getLabelList(circles[i]); } }; this.calculatePlacenameTags = function() { var cloud = this; var unselectedStyles = []; var selectedStyles = []; var hoverStyles = []; for (var k = 0; k < this.placeLabels.length; k++) { var c = GeoTemConfig.getColor(this.circle.circles[k].search); if( map.options.useGraphics ){ c = map.config.getGraphic(this.circle.circles[k].search).color; } var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; var color1 = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; var allStyles = "", hoverStyle = "", highlightStyle = "", selectedStyle = "", unselectedStyle = ""; if (GeoTemConfig.ie) { highlightStyle += map.options.ieHighlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; hoverStyle += map.options.ieHoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; selectedStyle += map.options.ieSelectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; unselectedStyle += map.options.ieUnselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; } else { highlightStyle += map.options.highlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; hoverStyle += map.options.hoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; selectedStyle += map.options.selectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; unselectedStyle += map.options.unselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; } allStyles += 'margin-right:5px;'; allStyles += 'margin-left:5px;'; unselectedStyles.push(unselectedStyle); selectedStyles.push(selectedStyle); hoverStyles.push(hoverStyle); var clickFunction = function(label, id) { label.div.onmouseover = function() { if (!label.opposite) { var oppositeLabel, oppositeLabelDiv; label.div.setAttribute('style', allStyles + "" + selectedStyles[id]); var c = GeoTemConfig.getColor(id); if( map.options.useGraphics ){ c = map.config.getGraphic(id).color; } var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; if (id == 0) { for (var i = 0; i < cloud.droppedLabels[1].length; i++) { if (cloud.droppedLabels[1][i].place == label.place) { oppositeLabel = cloud.droppedLabels[1][i]; cloud.rightDiv.appendChild(oppositeLabel.div); cloud.drawLine(cloud.ctxOl, label.div, oppositeLabel.div); var olDiv = cloud.othersLabels[1].div; olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + (cloud.othersLabels[1].weight - oppositeLabel.weight) + ')'); break; } } } else { for (var i = 0; i < cloud.droppedLabels[0].length; i++) { if (cloud.droppedLabels[0][i].place == label.place) { oppositeLabel = cloud.droppedLabels[0][i]; cloud.leftDiv.appendChild(oppositeLabel.div); cloud.drawLine(cloud.ctxOl, oppositeLabel.div, label.div); var olDiv = cloud.othersLabels[0].div; olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + (cloud.othersLabels[0].weight - oppositeLabel.weight) + ')'); break; } } } if ( typeof oppositeLabel == 'undefined') { oppositeLabel = { div : cloud.naDiv }; if (id == 0) { cloud.rightDiv.appendChild(cloud.naDiv); cloud.drawLine(cloud.ctxOl, label.div, cloud.naDiv); oppositeLabel.div.setAttribute('style', allStyles + "" + selectedStyles[1]); } else { cloud.leftDiv.appendChild(cloud.naDiv); cloud.drawLine(cloud.ctxOl, cloud.naDiv, label.div); oppositeLabel.div.setAttribute('style', allStyles + "" + selectedStyles[0]); } cloud.map.mapLabelHighlight(label); } else { cloud.map.mapLabelHighlight([label, oppositeLabel]); } label.div.onmouseout = function() { label.div.setAttribute('style', allStyles + "" + unselectedStyles[id]); var olDiv = cloud.othersLabels[0].div; olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + cloud.othersLabels[0].weight + ')'); var olDiv2 = cloud.othersLabels[1].div; olDiv2.innerHTML = olDiv2.innerHTML.replace(/\(\d*\)/g, '(' + cloud.othersLabels[1].weight + ')'); $(oppositeLabel.div).remove(); cloud.ctxOl.clearRect(0, 0, cloud.cvOl.width, cloud.cvOl.height); cloud.map.mapLabelHighlight(); } } } } var maxLabelSize = this.count for (var i = 0; i < this.placeLabels[k].length; i++) { var l = this.placeLabels[k][i]; l.selected = false; var div = document.createElement("div"); div.setAttribute('class', 'tagCloudItem'); var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; if (l.place == "all") { fontSize = 1; } div.style.fontSize = fontSize + "em"; l.allStyle = allStyles + "font-size: " + fontSize + "em;"; l.selectedStyle = selectedStyle; l.unselectedStyle = unselectedStyle; l.hoverStyle = hoverStyle; div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; l.div = div; clickFunction(l, k); } for (var i = 0; i < this.droppedLabels[k].length; i++) { var l = this.droppedLabels[k][i]; l.selected = false; var div = document.createElement("div"); div.setAttribute('class', 'tagCloudItem'); var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; div.style.fontSize = fontSize + "em"; l.allStyle = allStyles + "font-size: " + fontSize + "em;"; l.selectedStyle = selectedStyle; l.unselectedStyle = unselectedStyle; l.hoverStyle = hoverStyle; div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; l.div = div; div.setAttribute('style', allStyles + "" + selectedStyle); } } this.naDiv = document.createElement("div"); this.naDiv.setAttribute('class', 'tagCloudItem'); var fontSize = 1; div.style.fontSize = fontSize + "em"; l.allStyle = allStyles + "font-size: " + fontSize + "em;"; l.selectedStyle = selectedStyle; l.unselectedStyle = unselectedStyle; l.hoverStyle = hoverStyle; this.naDiv.innerHTML = "Not available"; l.div = this.naDiv; if (map.options.labelGrid) { this.showPlacelabels(); } }; this.showPlacelabels = function() { this.leftDiv = document.createElement("div"); this.leftDiv.setAttribute('class', 'tagCloudDiv'); this.leftDiv.style.textAlign = 'right'; this.map.gui.mapWindow.appendChild(this.leftDiv); this.centerDiv = document.createElement("div"); this.centerDiv.setAttribute('class', 'tagCloudDiv'); this.centerDiv.style.opacity = 0.7; this.map.gui.mapWindow.appendChild(this.centerDiv); this.centerDivOl = document.createElement("div"); this.centerDivOl.setAttribute('class', 'tagCloudDiv'); this.centerDivOl.style.opacity = 0.7; this.map.gui.mapWindow.appendChild(this.centerDivOl); this.rightDiv = document.createElement("div"); this.rightDiv.setAttribute('class', 'tagCloudDiv'); this.rightDiv.style.textAlign = 'left'; this.map.gui.mapWindow.appendChild(this.rightDiv); for (var i = 0; i < this.placeLabels.length; i++) { for (var j = 0; j < this.placeLabels[i].length; j++) { if (i == 0) { this.leftDiv.appendChild(this.placeLabels[i][j].div); } else { this.rightDiv.appendChild(this.placeLabels[i][j].div); } this.placeLabels[i][j].div.setAttribute('style', this.placeLabels[i][j].allStyle + "" + this.placeLabels[i][j].unselectedStyle); } } this.placeTagCloud(); this.setCanvas(); }; this.placeTagCloud = function() { var lonlat = new OpenLayers.LonLat(this.circle.feature.geometry.x, this.circle.feature.geometry.y); var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); var radius = this.circle.feature.style.pointRadius; var lw = this.leftDiv.offsetWidth; var rw = this.rightDiv.offsetWidth; this.leftDiv.style.left = (pixel.x - radius - lw - 5) + "px"; this.rightDiv.style.left = (pixel.x + radius + 5) + "px"; var lh = this.leftDiv.offsetHeight; var rh = this.rightDiv.offsetHeight; var lt = pixel.y - lh / 2; var rt = pixel.y - rh / 2; this.leftDiv.style.top = lt + "px"; this.rightDiv.style.top = rt + "px"; }; this.setCanvas = function() { var height = Math.max(this.leftDiv.offsetHeight, this.rightDiv.offsetHeight); var top = Math.min(this.leftDiv.offsetTop, this.rightDiv.offsetTop); var left = this.leftDiv.offsetLeft + this.leftDiv.offsetWidth; this.width = this.rightDiv.offsetLeft - left; this.centerDiv.style.left = left + "px"; this.centerDiv.style.top = top + "px"; this.centerDiv.style.height = height + "px"; this.centerDiv.style.width = this.width + "px"; this.centerDivOl.style.left = left + "px"; this.centerDivOl.style.top = top + "px"; this.centerDivOl.style.height = height + "px"; this.centerDivOl.style.width = this.width + "px"; var cv = document.createElement("canvas"); this.centerDiv.appendChild(cv); if (!cv.getContext && G_vmlCanvasManager) { cv = G_vmlCanvasManager.initElement(cv); } cv.width = this.width; cv.height = height; ctx = cv.getContext('2d'); this.cvOl = document.createElement("canvas"); this.centerDivOl.appendChild(this.cvOl); if (!this.cvOl.getContext && G_vmlCanvasManager) { this.cvOl = G_vmlCanvasManager.initElement(this.cvOl); } this.cvOl.width = this.width; this.cvOl.height = height + 50; this.ctxOl = this.cvOl.getContext('2d'); for (var i = 0; i < this.placeLabels[0].length; i++) { this.placeLabels[0][i].opposite = false; } for (var i = 0; i < this.placeLabels[1].length; i++) { this.placeLabels[1][i].opposite = false; } for (var i = 0; i < this.placeLabels[0].length; i++) { for (var j = 0; j < this.placeLabels[1].length; j++) { if (this.placeLabels[0][i].place == this.placeLabels[1][j].place) { this.drawLine(ctx, this.placeLabels[0][i].div, this.placeLabels[1][j].div); this.placeLabels[0][i].opposite = true; this.placeLabels[1][j].opposite = true; } } } } this.drawLine = function(ctx, label1, label2) { var x1 = 5; var x2 = this.width - 5; var y1 = label1.offsetTop + label1.offsetHeight / 2; var y2 = label2.offsetTop + label2.offsetHeight / 2; if (this.leftDiv.offsetTop > this.rightDiv.offsetTop) { y1 += this.leftDiv.offsetTop - this.rightDiv.offsetTop; } else { y2 += this.rightDiv.offsetTop - this.leftDiv.offsetTop; } ctx.lineCap = 'round'; ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.strokeStyle = '#555'; ctx.stroke(); } this.remove = function() { $(this.leftDiv).remove(); $(this.rightDiv).remove(); $(this.centerDiv).remove(); $(this.centerDivOl).remove(); }; };