Leaflet - Change and revert polygon feature style - leaflet

I make a little app using leaflet to display information about polygons.
Here's how the code works :
A crosshair is displayed in the center of the screen on top of the map
When map pans, crosshair remains in the center on the screen
When crosshair overlaps a polygon, polygon information is displyed in a div
the purpose of this system is to help polygon selecting on mobile for very small polygons
I came up with the following app : https://www.laurentgontier.com/Crosshair/
I need to be able to change polygon style when it is overlaped by crosshair and revert to default style when crosshair leaves polygon.
so far, I wasn't able to achieve this.
Here's the part of code :
//Geojson layer display
var geojsonLayer = new L.GeoJSON.AJAX("map.geojson",{
onEachFeature: onEachFeature
});
geojsonLayer.addTo(map);
//Crosshair display
var crosshairIcon = L.icon({
iconUrl: 'Cible.png',
iconSize: [30, 30], // size of the icon
iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
});
crosshair = new L.marker(map.getCenter(), {icon: crosshairIcon, clickable:false});
crosshair.addTo(map);
// Move the crosshair to the center of the map when the user pans
map.on('move', function(e) {
crosshair.setLatLng(map.getCenter());
});
// Move the crosshair to the center of the map when the user pans
map.on('moveend', function(e) {
var hasHit = false;
var newCenter = map.getCenter();
geoJsonLayers.forEach(function(layer){
var currLayerFeature = layer.feature;
var layerPlace = currLayerFeature.properties.Place;
var layerCoordinates = currLayerFeature.geometry.coordinates[0]
var xp = [], yp =[];
for(var i = 0; i<layerCoordinates.length; i++){
xp.push(layerCoordinates[i][0]); yp.push(layerCoordinates[i][1]);
}
if(checkPointForHit(xp, yp , newCenter.lng, newCenter.lat)){
displayPlace.innerHTML = layerPlace; hasHit = true}
})
if(!hasHit)displayPlace.innerHTML = 'Not overlaping polygon'
});
function checkPointForHit(xp/*array of xpointsOfPolygon*/, yp /*array of ypointsOfPolygon*/, x, y) {
var i, j, c = 0, npol = xp.length;
for (i = 0, j = npol-1; i < npol; j = i++) {
if ((((yp[i] <= y) && (y < yp[j])) ||
((yp[j] <= y) && (y < yp[i]))) &&
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])) {
c =!c;
}
}
return c;
}
Any idea about that ?

Use the turfjs library and then use booleanContains:
map.on('moveend', function(e) {
var hasHit = false;
geojsonLayer.resetStyle()
geoJsonLayers.forEach(function(layer){
var layerPlace = layer.feature.properties.Place;
if(turf.booleanContains(layer.toGeoJSON(),crosshair.toGeoJSON())){
displayPlace.innerHTML = layerPlace;
hasHit = true;
layer.setStyle({color: 'red'});
}
})
if(!hasHit){
displayPlace.innerHTML = 'Not overlaping polygon';
}
});
When you change the event from moveend to move the color is updated while moveing
Add DOM Script
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://cdn.jsdelivr.net/npm/#turf/turf#5.1.6/turf.min.js';
document.getElementsByTagName('head')[0].appendChild(script);
map.on('move moveend', function(e) {
var hasHit = false;
var newCenter = map.getCenter();
geojsonLayer.resetStyle()
geoJsonLayers.forEach(function(layer){
var layerPlace = layer.feature.properties.Place;
if(turf.booleanContains(layer.toGeoJSON(),crosshair.toGeoJSON())){
displayPlace.innerHTML = layerPlace;
hasHit = true;
layer.setStyle({color: 'red'});
}
})
if(!hasHit){
displayPlace.innerHTML = 'Not overlaping polygon';
}
});

Related

One pushpin click opens them all

Need help troubleshooting. All of the pushpins open upon clicking a single one opens up every pushpin infobox. I want there to be one pushpin infobox that changes each time a pushpin is clicked, only allowing one infobox to be open at a time.
// BING MAP Java Script
var map = null;
var pinid = 0;
var arrPinInfobox = [];
//Bing V8 start
function GetMap() { //LocInfo, Lat, Long
var _MapElement = document.getElementById("myMap");
if (_MapElement === null || typeof _MapElement === "undefined")
return;
if(jQuery("#pagesitemap_4_noMap").length < 0)
return;
var arrLocInfoRec = [];
var arrLLAdder = [];
var MapCenterLat;
var MapCenterLong;
var ZoomFactor;
var ZipLLSource = jQuery("#hdnZipLL").val();
var LocInfo = jQuery("#hdnCompleteLocInfo").val();
var ZipLL = [];
var Lat = "";
var Long ="";
console.log("Long");
if(typeof LocInfo === "undefined")
{
console.log("locInfo Undefined");
return;
}
if (ZipLLSource.length > 0) {
ZipLL = (ZipLLSource).split("`");
}
if (LocInfo.length > 0) {
arrLocInfoRec = LocInfo.split("|")
}
if (Lat.length > 0 && Long.length > 0) {
MapCenterLat = parseFloat(Lat);
MapCenterLong = parseFloat(Long);
ZoomFactor = 11; //16
}
else if (ZipLL.length >= 2) {
MapCenterLat = parseFloat(ZipLL[0]);
MapCenterLong = parseFloat(ZipLL[1]);
ZoomFactor = 11;
}
var mapOptions = {
credentials: ' ',
center: new Microsoft.Maps.Location(MapCenterLat, MapCenterLong),
mapTypeId: Microsoft.Maps.MapTypeId.Automatic,
zoom: ZoomFactor,
showScalebar: true
}
map = new Microsoft.Maps.Map('#myMap', mapOptions);
var arrPins = [];
var arrPinCenter = [];
//Generating Pins for multiple locations with Lat,Long
for (var locNum = 0; locNum <= arrLocInfoRec.length - 1; locNum++) {
try {
arrLLAdder = arrLocInfoRec[locNum].split("`");
if (arrLLAdder.length >= 13) {
//var latlong = arrLLAdder[11].split(',');
arrPinCenter[locNum] = new Microsoft.Maps.Location(parseFloat(arrLLAdder[11]), parseFloat(arrLLAdder[12]));
arrPinCenter[locNum] = new Microsoft.Maps.Location(parseFloat(arrLLAdder[11]), parseFloat(arrLLAdder[12]));
arrPins[locNum] = new Microsoft.Maps.Pushpin(
arrPinCenter[locNum], {
text: arrLLAdder[8] ,
icon: 'https://www.bingmapsportal.com/Content/images/poi_custom.png',
anchor: new Microsoft.Maps.Point(12, 39)
}
);
var adder = arrLLAdder[2] + '\r\n' + arrLLAdder[4] + '\r\n' + arrLLAdder[6] + arrLLAdder[9] + "\r\n" + arrLLAdder[1]
// Create the infobox for the pushpin
arrPinInfobox[locNum] = new Microsoft.Maps.Infobox(arrPins[locNum].getLocation(),
{ width: 350,
height: 100,
title: arrLLAdder[5],
description: adder,
offset: new Microsoft.Maps.Point(-3,13),
visible: false
});
// Add handler for the pushpin click event.
Microsoft.Maps.Events.addHandler(arrPins[locNum], 'click', displayInfobox);
// Add the Push Pins and InfoBox to the map all at once
if(arrPins.length > 0) {
map.entities.push(arrPins); //[locNum]
}
}
else {
console.log("Invalid Data: arrLocInfoRec[" + locNum + "] = \"" + arrLocInfoRec[locNum] + "\"");
}
} catch (e) {
console.log(e.message + "\r\n" + arrLocInfoRec[locNum]);
}
}
}
function displayInfobox(e) {
//map.entities.push(arrPinInfobox);
console.log("DisplayBox");
for(var i in arrPinInfobox){
arrPinInfobox[i].setOptions({ visible: true });
arrPinInfobox[parseInt(e.target.getText()) - 1].setOptions({ visible: true });
var infobox = arrPinInfobox[i];
infobox.setMap(map);
}
}
Your code in the displayInfobox function loops through all your infoboxes and sets visible to true and adding them to the map. Your code is functioning how it was written.
What you want to do is filter out your infoboxes. Personally I hate the whole array of infobox idea, it is messy. I believe I've recommended before the idea of creating a single infobox and reusing it when a pushpin is clicked. That is the best approach if you only need one infobox to appear at a time. If you want to be able to show multiple infoboxes at a time, store the reference to the infobox in the pushpin some how. All shapes in Bing Maps has a metadata property reserved for your custom data. Also just noticed you add the array of pushpins to the map several times, this will cause issues. Here is a proposed change to your code, I've added a comment with // Ricky: to indicate the changes I made:
// BING MAP Java Script
var map = null;
var pinid = 0;
var arrPinInfobox = [];
//Bing V8 start
function GetMap() { //LocInfo, Lat, Long
var _MapElement = document.getElementById("myMap");
if (_MapElement === null || typeof _MapElement === "undefined")
return;
if(jQuery("#pagesitemap_4_noMap").length < 0)
return;
var arrLocInfoRec = [];
var arrLLAdder = [];
var MapCenterLat;
var MapCenterLong;
var ZoomFactor;
var ZipLLSource = jQuery("#hdnZipLL").val();
var LocInfo = jQuery("#hdnCompleteLocInfo").val();
var ZipLL = [];
var Lat = "";
var Long ="";
console.log("Long");
if(typeof LocInfo === "undefined")
{
console.log("locInfo Undefined");
return;
}
if (ZipLLSource.length > 0) {
ZipLL = (ZipLLSource).split("`");
}
if (LocInfo.length > 0) {
arrLocInfoRec = LocInfo.split("|")
}
if (Lat.length > 0 && Long.length > 0) {
MapCenterLat = parseFloat(Lat);
MapCenterLong = parseFloat(Long);
ZoomFactor = 11; //16
}
else if (ZipLL.length >= 2) {
MapCenterLat = parseFloat(ZipLL[0]);
MapCenterLong = parseFloat(ZipLL[1]);
ZoomFactor = 11;
}
var mapOptions = {
credentials: ' ',
center: new Microsoft.Maps.Location(MapCenterLat, MapCenterLong),
mapTypeId: Microsoft.Maps.MapTypeId.Automatic,
zoom: ZoomFactor,
showScalebar: true
}
map = new Microsoft.Maps.Map('#myMap', mapOptions);
var arrPins = [];
var arrPinCenter = [];
//Generating Pins for multiple locations with Lat,Long
for (var locNum = 0; locNum <= arrLocInfoRec.length - 1; locNum++) {
try {
arrLLAdder = arrLocInfoRec[locNum].split("`");
if (arrLLAdder.length >= 13) {
//var latlong = arrLLAdder[11].split(',');
arrPinCenter[locNum] = new Microsoft.Maps.Location(parseFloat(arrLLAdder[11]), parseFloat(arrLLAdder[12]));
arrPins[locNum] = new Microsoft.Maps.Pushpin(arrPinCenter[locNum], {
text: arrLLAdder[8] ,
icon: 'https://www.bingmapsportal.com/Content/images/poi_custom.png',
anchor: new Microsoft.Maps.Point(12, 39)
});
var adder = arrLLAdder[2] + '\r\n' + arrLLAdder[4] + '\r\n' + arrLLAdder[6] + arrLLAdder[9] + "\r\n" + arrLLAdder[1]
// Create the infobox for the pushpin
//Ricky: Add your infobox as a reference in your pushpin
arrPins[locNum]. metadata = new Microsoft.Maps.Infobox(arrPins[locNum].getLocation(),
{ width: 350,
height: 100,
title: arrLLAdder[5],
description: adder,
offset: new Microsoft.Maps.Point(-3,13),
visible: false
});
// Add handler for the pushpin click event.
Microsoft.Maps.Events.addHandler(arrPins[locNum], 'click', displayInfobox);
}
else {
console.log("Invalid Data: arrLocInfoRec[" + locNum + "] = \"" + arrLocInfoRec[locNum] + "\"");
}
} catch (e) {
console.log(e.message + "\r\n" + arrLocInfoRec[locNum]);
}
}
// Add the Push Pins and InfoBox to the map all at once
//Ricky: Moved this out of the array as you only need to add array of pushpins to the map once.
if(arrPins.length > 0) {
map.entities.push(arrPins); //[locNum]
}
}
function displayInfobox(e) {
//map.entities.push(arrPinInfobox);
console.log("DisplayBox");
//Get infobox from the pushpin, rather than looping through array.
var infobox = e.target.metadata;
infobox.setOptions({ visible: true });
//for(var i in arrPinInfobox){
//arrPinInfobox[i].setOptions({ visible: true });
//arrPinInfobox[parseInt(e.target.getText()) - 1].setOptions({ visible: true });
//var infobox = arrPinInfobox[i];
//infobox.setMap(map);
//}
}
If you want to clean up your code some more I recommend:
get rid of all the array's, there is no need for them.
Use a layer for your pushpins. Add a single click event on the layer rather than on each individual pushpin.

Chart.js click on labels, using bar chart

i need help with my Chart.js interactivity. When I click on the label, I need to return the column(index) number at which I clicked.
I tried to use getElementsAtEvent but it only work if I click directly at chart.
This http://jsfiddle.net/yxz2sjam/ is pretty much what I am looking for but getPointsAtEvent is no longer available in the new versions.
canvas.onclick = function (evt) {
var points = chart.getPointsAtEvent(evt);
alert(chart.datasets[0].points.indexOf(points[0]));
};
I also found this http://jsfiddle.net/1Lngmtz7/ but it isn't working with bar chart.
var ctx = document.getElementById("myChart").getContext("2d");
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data
})
$('#myChart').click(function (e) {
var helpers = Chart.helpers;
var eventPosition = helpers.getRelativePosition(e, myRadarChart.chart);
var mouseX = eventPosition.x;
var mouseY = eventPosition.y;
var activePoints = [];
helpers.each(myRadarChart.scale.ticks, function (label, index) {
for (var i = this.getValueCount() - 1; i >= 0; i--) {
var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5);
var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize);
var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle);
var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily);
var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
ctx.font = pointLabeFont;
var labelsCount = this.pointLabels.length,
halfLabelsCount = this.pointLabels.length / 2,
quarterLabelsCount = halfLabelsCount / 2,
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
var width = ctx.measureText(this.pointLabels[i]).width;
var height = pointLabelFontSize;
var x, y;
if (i === 0 || i === halfLabelsCount)
x = pointLabelPosition.x - width / 2;
else if (i < halfLabelsCount)
x = pointLabelPosition.x;
else
x = pointLabelPosition.x - width;
if (exactQuarter)
y = pointLabelPosition.y - height / 2;
else if (upperHalf)
y = pointLabelPosition.y - height;
else
y = pointLabelPosition.y
if ((mouseY >= y && mouseY <= y + height) && (mouseX >= x && mouseX <= x + width))
activePoints.push({ index: i, label: this.pointLabels[i] });
}
}, myRadarChart.scale);
var firstPoint = activePoints[0];
if (firstPoint !== undefined) {
alert(firstPoint.index + ': ' + firstPoint.label);
}
});
Thank for response.
I solve the problem with
document.getElementById("chart").onclick = function(e)
{
var activeElement = weatherMainChart.lastTooltipActive;
console.log(activeElement[0]._index);
};
this solution register clicks on chart and label, then I restricted it with e.layerY to register only clicks on label section.
document.getElementById("chart").onclick = function(e)
{
var activeElement = weatherMainChart.lastTooltipActive;
if(e.layerY > 843 && e.layerY < 866 && activeElement[0] !== undefined)
console.log(activeElement[0]._index);
};
If you add a click handler through the onClick option you can use the following code using the getElementsAtEventForMode() call:
function handleClick(evt) {
var col;
switch(chartType) {
case "horizontalBar":
this.getElementsAtEventForMode(evt, "y", 1).forEach(function(item) { col = item._index });
break;
case "bar":
this.getElementsAtEventForMode(evt, "x", 1).forEach(function(item) { col = item._index });
break;
}
if (!col) {
return;
}
alert("Column " + col + " was selected");
};
You'll probably need to add extra switch checks for other chart types but I'm sure you get the idea.
Using version 2.4.0, i created an onClick Event, and inside it
var activeIndex = localChart.tooltip._lastActive[0]._index;
var clickCoordinates = Chart.helpers.getRelativePosition(e, localChart.chart);
if (clickCoordinates.y >= 530) { //custom value, depends on chart style,size, etc
alert("clicked on " + localChart.data.labels[activeIndex]);
}
I Solved this problem with single or multiple label click you will be find using true/false
First you need to set your chartJs Id click
below code SessionChart = Your ChartJs ID e.g. ("myChart") I was replace it for my Id
document.getElementById("SessionChart").onclick = function (evt) {
var meta = SubscriberSessionChart.getDatasetMeta(0);
if (meta.$filler.chart.legend.legendItems[0].text.toLowerCase() "sessions")
{
if (meta.$filler.chart.legend.legendItems[0].hidden) {
sessionHidden = true;
}
}
}
here "sessions" = first label text
meta.$filler.chart.legend.legendItems[0].text.toLowerCase() = is your first label
from Array so you can get multiple label's click here true / false
if (meta.$filler.chart.legend.legendItems[0].hidden) = your label is not active then
you will get hidden true otherwise you will get false if not tick on label
by default label tick hidden is false in chart js

leaflet marker dragging moves map

I am working on OSM using leaflet..I enable dragging:true on my destination marker as I need it to be draggable ,but while dragging marker my MAP also moves .Is there a way I can only move the marker.
$(document).ready(function()
{
homepg();
});
var cab_map = null;
function homepg()
{
var str = '';
var markers = new L.MarkerClusterGroup();
var lat = '19.068246';
var lng = '72.850638';
cab_map = ddmap.init('mapdivcab',[lat,lng],14);
ddmap.getDirection(13.039680,77.580214,13.040850,77.625532,cab_map,'lmenu');
}
getDirection: function(flat,flon,tlat,tlon,map,mapdv)
{
this.dirMap = map;
this.mapDiv = mapdv;
this.sourceLatLng = new L.LatLng(flat,flon);
this.targetLatLng = new L.LatLng(tlat,tlon);
if(this.fScript)
head.removeChild(fScript);
fScript = document.createElement('script');
fScript.setAttribute("type","text/javascript");
fScript.setAttribute("src", ddmap.serverUrl+"jsonp=ddmap.updateAddressFrom/nearbylocation/"+flat.toFixed(6).replace('.','')+"/"+flon.toFixed(6).replace('.','')+"/1?json_callback=%jsonp");
document.getElementsByTagName("head")[0].appendChild(fScript);
if(this.tScript)
head.removeChild(tScript);
tScript = document.createElement('script');
tScript.setAttribute("type","text/javascript");
tScript.setAttribute("src", ddmap.serverUrl+"jsonp=ddmap.updateAddressTo/nearbylocation/"+tlat.toFixed(6).replace('.','')+"/"+tlon.toFixed(6).replace('.','')+"/1?json_callback=%jsonp");
document.getElementsByTagName("head")[0].appendChild(tScript);
if(this.currentScript)
head.removeChild(currentScript);
currentScript = document.createElement('script');
currentScript.setAttribute("type","text/javascript");
currentScript.setAttribute("src", "viaroute?z=13&output=json&jsonp=ddmap.showRoute&loc="+flat+","+flon+"&loc="+tlat+","+tlon+"&instructions=true");
document.getElementsByTagName("head")[0].appendChild(currentScript);
}
showRoute: function(response) {
var geometry = this._decode(response.route_geometry, 6);
var route = new L.Polyline( [], {dashArray:""} );
route.setLatLngs( geometry );
var sIcon = L.icon({iconUrl:this.imageHost+"/images/marker-source.png",iconAnchor:[10,30],shadowUrl: this.imageHost+'/images/marker-shadow.png'});
var tIcon = L.icon({iconUrl:this.imageHost+"/images/marker-target.png",iconAnchor:[10,30],shadowUrl: this.imageHost+'/images/marker-shadow.png'});
mrkrSrc = L.marker(this.sourceLatLng, {icon: sIcon});
mrkrTgt = L.marker(this.targetLatLng, {icon: tIcon,draggable:'true'});
if(this.mainLayer)
this.dirMap.removeLayer(this.mainLayer);
this.mainLayer = L.layerGroup([mrkrSrc, mrkrTgt])
.addLayer(route)
.addTo(this.dirMap);
var bounds = new L.LatLngBounds(this.sourceLatLng, this.targetLatLng);
this.dirMap.fitBounds(bounds);
this.showRouteDesc(response,geometry);
//
mrkrTgt.on('drag', function(event){
var marker = event.target;
var dst = marker.getLatLng();
var src = mrkrSrc.getLatLng();
ddmap.getroute(src.lat,src.lng,dst.lat,dst.lng,cab_map,'lmenu');//instead of calling getDriection i m calling this function
});
//this function is same as getDirection but i have removed some code, thought that is not required and it was making 'drag event' rough and time taking
getroute: function(flat,flon,tlat,tlon,map,mapdv)
{
this.dirMap = map;
this.mapDiv = mapdv;
this.sourceLatLng = new L.LatLng(flat,flon);
this.targetLatLng = new L.LatLng(tlat,tlon);
if(this.currentScript)
head.removeChild(currentScript);
currentScript = document.createElement('script');
currentScript.setAttribute("type","text/javascript");
currentScript.setAttribute("src", "viaroute?z=13&output=json&jsonp=ddmap.showRoute&loc="+flat+","+flon+"&loc="+tlat+","+tlon+"&instructions=true");
document.getElementsByTagName("head")[0].appendChild(currentScript);
}

Chart js - avoid overlapping of tooltips in pie chart

I've used chart js library for make pie chart. I want to display tooltips always. I've done this. I've attached screenshot.
But now the tooltips are overlapped . How to solve this?
This is my code
myPieChart = new Chart(pie_chart).Pie(data_results.comp.pie, {
tooltipTemplate: "<%= value %> %",
scaleFontSize: 14,
scaleFontColor: "#333",
tooltipFillColor: "rgba(0,0,0,0)",
onAnimationComplete: function()
{
this.showTooltip(this.segments, true);
},
tooltipEvents: [],
tooltipFontColor: "#000",
});
I want to change tooltip position if already one present in that position.
Actually to detect overlapping tooltips is very difficult.
I solved it in the end by deactivating the color in the toolbox, reducing the size of the tooltip, moving the tooltip closer to the outer border and hiding all tooltips, which represent less than 2%. Example looks like that:
I used for that the following code:
Chart.Tooltip.positioners.outer = function(elements) {
if (!elements.length) {
return false;
}
var i, len;
var x = 0;
var y = 0;
for (i = 0, len = elements.length; i < len; ++i) {
var el = elements[i];
if (el && el.hasValue()) {
var elPosX = el._view.x+0.95*el._view.outerRadius*Math.cos((el._view.endAngle-el._view.startAngle)/2+el._view.startAngle);
var elPosY = el._view.y+0.95*el._view.outerRadius*Math.sin((el._view.endAngle-el._view.startAngle)/2+el._view.startAngle);
if (x < elPosX) {
x = elPosX;
}
if (y < elPosY) {
y = elPosY;
}
}
}
return {
x: Math.round(x),
y: Math.round(y)
};
},
Chart.pluginService.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
if ((sector._view.endAngle-sector._view.startAngle) > 2*Math.PI*0.02) {
chart.pluginTooltips.push(
new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart)
);
}
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip._options.position = "outer";
tooltip._options.displayColors = false;
tooltip._options.bodyFontSize = tooltip._chart.height*0.025;
tooltip._options.yPadding = tooltip._options.bodyFontSize*0.30;
tooltip._options.xPadding = tooltip._options.bodyFontSize*0.30;
tooltip._options.caretSize = tooltip._options.bodyFontSize*0.5;
tooltip._options.cornerRadius = tooltip._options.bodyFontSize*0.50;
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});

Integrating / adding Google Earth View to my map

I am creating an interactive map for a non profit association "Friends of Knox Mountain Park" but I am getting trouble with the Google Earth view.
I've been searching on the web for weeks and none of the solutions I found works for me. Can someone take a look of the code and let me know what I should do to include Google Earth View in the map? Thanks in advance.
The online project: http://www.virtualbc.ca/knoxmountain/
And this is the javascript file (mapa2.js) containing the google map's code:
google.load('earth', '1');
var map;
var googleEarth;
var gmarkers = [];
var iconShadow = new google.maps.MarkerImage('icons/shadow.png',
new google.maps.Size(46, 42),
new google.maps.Point(0,0),
new google.maps.Point(13, 42));
var sites = [
['Apex Trail - Shelter',49.91174271, -119.48507050, 4, '<img src="images/apex_point_high.jpg">','magenta','14'],
['Apex Trail',49.91286999, -119.48413424, 3, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Gordon Trail',49.91971281, -119.47954356, 2, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Paul Tomb Bay',49.92555541, -119.47710250, 1, '<img src="images/tomb_bay.jpg">','lemon','1']
];
var infowindow = null;
var overlay;
// Used to make Google Map quard coords to MapCruncher/BingMaps quard coords
function TileToQuadKey ( x, y, zoom)
{
var quad = "";
for (var i = zoom; i > 0; i--)
{
var mask = 1 << (i - 1);
var cell = 0;
if ((x & mask) != 0)
cell++;
if ((y & mask) != 0)
cell += 2;
quad += cell;
}
return quad;
}
function init() {
var centerMap = new google.maps.LatLng(49.909671, -119.482241);
var myOptions = {
zoom: 10,
center: centerMap,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Create the tile layers
// ASTER Tile Layer
myASTEROptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "ASTER",
minZoom:13,
maxZoom:20
}
ASTERMapType = new google.maps.ImageMapType( myASTEROptions );
map.overlayMapTypes.insertAt(0, ASTERMapType);
// Aerial Tile Layer
myAerialOptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "Aerial",
minZoom:15,
maxZoom:21
}
AerialMapType = new google.maps.ImageMapType( myAerialOptions );
map.overlayMapTypes.insertAt(1, AerialMapType);
var panorama = new google.maps.StreetViewPanorama(map.getDiv());
panorama.setVisible(false);
panorama.set('enableCloseButton', true);
map.setStreetView(panorama);
panorama.setPosition(centerMap);
setMarkers(map, sites);
setZoom(map, sites);
infowindow = new google.maps.InfoWindow({
content: "Loading..."
});
googleEarth = new GoogleEarth(map);
google.maps.event.addListenerOnce(map, 'tilesloaded', addOverlays);
}
/*
This functions sets the markers (array)
*/
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var site = markers[i];
var siteLatLng = new google.maps.LatLng(site[1], site[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
title: site[0],
zIndex: site[3],
html: site[4],
// Markers drop on the map
animation: google.maps.Animation.DROP,
icon: 'http://www.virtualbc.ca/knoxmountain/icons/icon.png',
shadow: iconShadow
});
gmarkers.push(marker);
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
/*
Set the zoom to fit comfortably all the markers in the map
*/
function setZoom(map, markers) {
var boundbox = new google.maps.LatLngBounds();
for ( var i = 0; i < markers.length; i++ )
{
boundbox.extend(new google.maps.LatLng(markers[i][1], markers[i][2]));
}
map.setCenter(boundbox.getCenter());
map.fitBounds(boundbox);
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(gmarkers[i-1], "click");
}
google.maps.event.addDomListener(window, 'load', init);
The first issue I notice with your site is you are linking to http://www.virtualbc.ca/src/googleearth-compiled.js which does not exist.