discourse-legacysite-perl/site/common/static/js/map.js
2024-06-17 22:27:49 +10:00

1003 lines
25 KiB
JavaScript

jQuery( document ).ready( function() {
/* Variables */
var isMobile = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/);
/*
* Google Map Ajax
* ----------------------- */
$(".js-ajax-php-json").submit(function(){
var data = {
"action": "test"
};
data = $(this).serialize() + "&" + $.param(data);
$.ajax({
type: "POST",
dataType: "json",
url: "googlemaps/map_json.php",
data: data,
success: function(data) {
$(".the-return").html(
data
);
}
});
return false;
});
/*
* Google Map Display
* ------------------------ */
var markers = [];
var newMarkers= [];
var mapCategories = [];
var markerJSON;
var dofitbounds = true;
var myMarkerClusterer = null;
var storageKey = $('.map').data('name');
var jsonURL = $('.map').data('json');
var mapCenterLatLng = loadStorage( 'mapCenterLatLng' );
var map = null;
var color = '#00000';
var maxzoom = 7;
var size = 30;
var month = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];
var styles = [
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [
{ "color": "#B4E484" }
]
},{
"featureType": "water",
"stylers": [
{ "color": "#72DAFF" }
]
},{
"featureType": "road.local",
"elementType": "geometry",
"stylers": [
{ "visibility": "simplified" },
{ "color": "#ffffff" }
]
},{
"featureType": "transit" },{
"featureType": "road.highway",
"elementType": "geometry",
"stylers": [
{ "visibility": "simplified" },
{ "color": "#ffffff" }
]
},{
"featureType": "road.local",
"stylers": [
{ "color": "#FFFFFF" },
{ "visibility": "simplified" }
]
},{
"elementType": "geometry" },{
"featureType": "landscape.man_made",
"elementType": "geometry",
"stylers": [
{ "color": "#F0EEE9" }
]
},{
"elementType": "labels.text.fill",
"stylers": [
{ "saturation": -100 },
{ "gamma": 0.88 }
]
}
];
// Create a new StyledMapType object, passing it the array of styles,
// as well as the name to be displayed on the map type control.
var markerIcons = [];
if ( $('.map').length > 0 ) {
// Load the xml file using ajax
runMapScripts();
}
function showLog( logs ) {
if ( window.location.href.indexOf('dev') >= 0 || window.location.href.indexOf('localhost') >= 0 ) {
console.log( logs );
}
return;
}
function runMapScripts() {
var styledMap = new google.maps.StyledMapType(styles,
{name: "Map"});
if ( mapCenterLatLng === false || mapCenterLatLng === undefined || mapCenterLatLng.lat === null ) {
mapCenterLatLng = new google.maps.LatLng(30.447275, -100.821923);
saveStorage( 'mapCenterLatLng', mapCenterLatLng );
}
markerIcons = {
'race': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(0, 460)),
'triclub': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(38, 460)),
'coach': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(78, 460)),
'runshop': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(118, 460)),
'retailer': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(158, 460)),
'fitter': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(198, 460)),
'roadshow': new google.maps.MarkerImage("/articles/static/css/images/sprite.svg",
new google.maps.Size(35, 50),
new google.maps.Point(0, 505)),
};
loadMap(); //generate blank google map
loadMapData(); //refresh google map with marker(s) data
mapOfEverything(); //setup map of everything
}
if ( $('.map-control .text-input').length > 0 ) {
updateMapPerLocationInput();
}
//val = window.location.search.replace("?", "");
function parseSecond(val) {
var result = "Not found",
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === val) result = decodeURIComponent(tmp[1]);
}
return result;
}
function loadMapData() {
var refreshStorage = false; //
var lastmodified = loadStorage( 'lastModified' );
var query = window.location.search.replace("?", "");
var queryParsed = parseSecond( query );
if ( storageKey == 'single' )
refreshStorage = true;
if ( lastmodified !== false ) {
var now = Date.now();
if ( now >= lastmodified + 300 * 1000 )
refreshStorage = true; //5minutes
showLog( 'reload json', refreshStorage );
}
if ( loadStorage( storageKey ) === false || refreshStorage ) {
showLog( 'load storage ');
fetchMakersAndInitialize( storageKey, jsonURL );
} else {
showLog( 'from storage');
markerJSON = loadStorage( storageKey );
refreshMap();
//google.maps.event.addDomListener(window, 'load', initialize);
}
}
function fetchJson( storageKey, jsonURL, refresh ) {
var markerJSON;
$.ajax({
type: "GET",
url: jsonURL,
dataType: "json",
success: function (json) {
markerJSON = json;
storeMarkerJson( storageKey, markerJSON );
if ( refresh )
refreshMap();
}
}).fail( function(){
markerJSON = false;
});
}
function isDataReady() {
var ready = false;
if ( storageKey == 'everything' ) {
var storageKeys = jsonURL.split(',');
var total = storageKeys.length - 1;
for ( i = 1; i < storageKeys ; i++ ) {
if ( loadStorage( storageKeys[i] ) !== false )
counter++;
if ( counter === total )
ready = true;
//showLog( counter, storageKeys[i] );
}
} else if ( storageKey == 'single' ) {
} else {
if ( loadStorage( storageKey ) )
ready = true;
}
//showLog( counter, ready );
return ready;
}
function fetchMakersAndInitialize( storageKey, jsonURL ) {
var markerJSON;
var refresh = false;
if ( storageKey == 'single' ) {
//showLog('loading single marker');
refresh = true;
markerJSON = [{
"category": $('.map').data('category'),
"name": $('.details h2').text(),
"lat": $('.map').data('lat'),
"lng": $('.map').data('lng'),
"info1": $('.details .address').html() + $('.details .contact').html(),
"info2":"",
"info3":"",
"info4":"",
"phone":"",
"email":"",
"website":"",
"details": $('.details .race-info').html(),
}];
saveStorage( storageKey, markerJSON );
refreshMap();
} else if ( storageKey !== 'everything' ) {
refresh = true;
markerJSON = fetchJson( storageKey, jsonURL, refresh );
} else {
var jsons = jsonURL.split(",");
var jsonBase = jsons['0'];
for ( i = 1; i < jsons.length; i++ ) {
var thisURL = jsonBase + jsons[i] + '.json';
if ( i == ( jsons.length - 1 ) )
refresh = true;
fetchJson( jsons[i], thisURL, refresh );
}
}
}
function storeMarkerJson( storageKey, markerJSON ) {
if (markerJSON) {
saveStorage( storageKey, markerJSON );
}
}
function refreshMap() {
//showLog('refresh map', storageKey );
var markersData = [];
var i = 1;
if ( storageKey == 'everything' ) {
var storageKeys = jsonURL.split(',');
for ( i = 1; i < storageKeys.length; i ++ ) {
markersData = markersData.concat( loadStorage( storageKeys[i] ) );
}
} else {
markersData = loadStorage( storageKey );
}
var bounds = new google.maps.LatLngBounds();
if ( markersData ) {
for ( i = 0; i < markersData.length; ++i) {
var category = markersData[i].category;
if ( markersData[i] ) {
var latLng = new google.maps.LatLng( markersData[i].lat, markersData[i].lng);
var marker = new google.maps.Marker({
position: latLng,
draggable: false,
icon: markerIcons[category],
category: category,
});
var content = '<h4>' + markersData[i].name + '</h4>';
if ( category == 'race') {
if (markersData[i].details && storageKey == 'single') {
content += markersData[i].details;
}
else {
var raceDate = new Date( markersData[i].info1 );
raceDate = month[ raceDate.getMonth() ] + ' ' + raceDate.getDay() + ', ' + raceDate.getFullYear();
content = content + '<b>' + raceDate + '</b><br/>';
if ( markersData[i].info2.length > 0 )
content = content + markersData[i].info2 + ' kilometers swim<br/>';
if ( markersData[i].info3.length > 0 )
content = content + markersData[i].info3 + ' kilometers bike<br/>';
if ( markersData[i].info4.length > 0 )
content = content + markersData[i].info4 + ' kilometers run<br/>';
if ( markersData[i].phone.length > 0 )
content = content + 'Phone: ' + markersData[i].phone + '<br/>';
}
} else {
content = content + '<b>' + markersData[i].info1 + '<br/>';
if ( markersData[i].info2.length > 0 )
content = content + markersData[i].info2 + '<br/>';
if ( markersData[i].info3.length > 0 && markersData[i].info4.length > 0 )
content = content + markersData[i].info3 + ', ' + markersData[i].info4 + '</b><br/>';
if ( markersData[i].phone.length > 0 )
content = content + 'Phone: ' + markersData[i].phone + '<br/>';
if ( markersData[i].email.length > 0 )
content = content + '<a href="mailto:' + markersData[i].email + '" title="email">' + markersData[i].email + '</a><br/>';
if ( markersData[i].website.length > 0 )
content = content + '<a href="' + markersData[i].website + '" title="website">' + markersData[i].website.replace('http://', '') + '</a>';
}
if ( storageKey !== 'single' ) {
content = content +
'<br/><br/>' +
'<div class="center"><a href="' + markersData[i].details + '" class="btn" title="get details">Get Details</></div>';
} else {
content = content +
'<br/>' +
'<div class="center"><a href="https://maps.google.com?daddr=' + markersData[i].lat + ',' + markersData[i].lng+ '" class="btn" title="get details">Get Directions</></div>';
}
var infowindow = new google.maps.InfoWindow({
content: content
});
bindInfoWindow(marker, map, infowindow, unescape( content ) );
markers.push(marker);
bounds.extend(latLng);
//mapCenterLatLng = latLng;
}
}
newMarkers = markers;
}
//display clustered markers
myMarkerClusterer = new MarkerClusterer(map, markers, {
maxZoom: maxzoom,
gridSize: size,
});
//When there is only one marker, set zoom to 13
if ( map === null ) {
//single / one location
} else if ( markers.length === 1 ) {
//map.setCenter( mapCenterLatLng );
map.setZoom( 14 );
mapCenterLatLng = map.getCenter();
saveStorage( 'mapCenterLatLng' , mapCenterLatLng );
infowindow.open(map, markers['0']);
//show multiple locations
} else if ( markers.length > 1 ) {
//if ( dofitbounds )
// map.fitBounds(bounds);
//mapCenterLatLng = map.getCenter();
mapCenterLatLng = loadStorage( mapCenterLatLng );
//set a default center if .lat is not a number
if ( !isNaN( mapCenterLatLng.lat ) )
mapCenterLatLng = new google.maps.LatLng( mapCenterLatLng.lat, mapCenterLatLng.lng );
else
mapCenterLatLng = new google.maps.LatLng(38.447275, -88.821923);
//console.log( mapCenterLatLng );
map.setCenter ( mapCenterLatLng );
map.setZoom( 3 );
//showLog( 'save ', mapCenterLatLng );
//saveStorage( 'mapCenterLatLng' , mapCenterLatLng );
dofitbounds = false;
//no markers
} else {
//do nothing
}
saveMapCenter( map );
}
function saveMapCenter( map ) {
map.addListener('center_changed', function() {
// 3 seconds after the center of the map has changed, pan back to the
// marker.
saveStorage( 'mapCenterLatLng', map.getCenter() );
});
}
function checkMapCategories() {
if ( $('.map-category input').length > 0 ) {
$('.map-category input').change(function(){
mapCategories = [];
$('.map-category input').each( function(){
if ( $(this).prop('checked') )
mapCategories.push( $(this).val() );
});
filterMarkers( mapCategories );
});
}
toogleMapCategories();
}
function toogleMapCategories() {
$('.map-category .hide-button').click( function() {
if ( $(this).siblings().hasClass('collapsed') ) {
$('.collapsed').slideDown('200').removeClass('collapsed');
$(this).text( $(this).text().replace('Show', 'Hide').replace( '9660', '9650' ) );
}
else {
$(this).siblings().slideUp('200').addClass('collapsed');
$(this).text( $(this).text().replace('Hide', 'Show').replace( '9650', '9660' ) );
}
});
}
function filterMarkers( mapCategories ) {
newMarkers = [];
clearClusters();
if ( mapCategories.length > 0 ) {
for (i = 0; i < markers.length; i++) {
var marker = markers[i];
// If is same category or category not picked
if ( mapCategories.indexOf( marker.category ) >= 0 ) {
newMarkers.push( marker );
marker.setVisible(true);
}
// Categories don't match
else {
marker.setVisible(false);
}
}
refreshClusterer();
}
}
function refreshClusterer() {
//display clustered markers
myMarkerClusterer = new MarkerClusterer(map, newMarkers, {
maxZoom: maxzoom,
gridSize: size,
});
}
function resetClusterer() {
//display clustered markers
myMarkerClusterer = new MarkerClusterer(map, newMarkers, {
maxZoom: maxzoom,
gridSize: size,
});
}
function bindInfoWindow(marker, map, infowindow, description) {
marker.addListener('click', function() {
infowindow.setContent(description);
infowindow.open(map, this);
});
}
function loadMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 8,
center: mapCenterLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
maxZoom: '17',
scrollwheel: false,
draggable: false,
fullscreenControl: true,
mapTypeControlOptions: {
mapTypeId: google.maps.MapTypeId.HYBRID,
}
});
map.setOptions({styles: styles});
//Enable Scrolling and Dragging with Mouse Click (For Desktop)
google.maps.event.addListener(map, 'mousedown', function(){
enableScrollingWithMouseWheel();
if (!isMobile)
map.setOptions({ draggable: true });
});
//Enable Dragging with Double Tab/Click (For Desktop and Mobile)
google.maps.event.addListener(map, 'dblclick', function() {
map.setOptions({ draggable: true, scrollwheel: true });
});
}
function clearClusters() {
myMarkerClusterer.clearMarkers();
}
function enableScrollingWithMouseWheel() {
map.setOptions({ scrollwheel: true });
}
function disableScrollingWithMouseWheel() {
map.setOptions({ scrollwheel: false, draggable: false });
}
google.maps.event.addListenerOnce(map, 'idle', function(){
// do something only the first time the map is loaded
//Disable scrolling and dragging when clicking / tapping outside the map (For Desktop and Mobile)
$('body').on('mouseup', function(event) {
var clickedInsideMap = $(event.target).parents('#map').length > 0;
if(!clickedInsideMap) {
disableScrollingWithMouseWheel();
}
});
//Disable scrolling and dragging when scrolling the page with mousewheel (For Desktop)
$(window).scroll(function() {
disableScrollingWithMouseWheel();
});
});
function updateMapPerLocationInput() {
var address;
$('.map-control .text-input').keyup(function(e){
if (e.keyCode == 13) {
address = $(this).val();
if ( address.length > 3 ) {
getLatLng( address );
}
}
});
}
function setNewMapCenter( data ) {
var newLatLng = new google.maps.LatLng( data['0'], data['1'] );
map.setZoom( 7 );
map.setCenter( newLatLng );
var boundaryMarkers = find_closest_marker( data );
setBounds ( boundaryMarkers );
}
function distance(lat1, lon1, lat2, lon2) {
var p = 0.017453292519943295; // Math.PI / 180
var c = Math.cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}
function find_closest_marker( center ) {
var distances = [];
var lat1, lat2, lng1, lng2;
var boundaryMarkers;
if ( center ) {
lat1 = center['0'];
lng1 = center['1'];
for ( i = 0; i < newMarkers.length; i++) {
lat2 = newMarkers[i].getPosition().lat();
lng2 = newMarkers[i].getPosition().lng();
newMarkers[i].distance = distance( lat1, lng1, lat2, lng2 );
}
boundaryMarkers = sortByDistance( newMarkers );
return boundaryMarkers;
}
}
function sortByDistance( markerArray ) {
var fifthMarker = [];
markerArray.sort(function (a, b) {
if (a.distance > b.distance) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
// a must be equal to b
return 0;
});
firstMarker = markerArray.splice(0, 1)['0'];
fifthMarker = markerArray.splice(4, 1)['0'];
var boundaryMarkers = [ firstMarker, fifthMarker ];
return boundaryMarkers;
}
function setBounds( boundaryMarkers ){
if ( boundaryMarkers ) {
var bounds = new google.maps.LatLngBounds();
bounds.extend( boundaryMarkers['0'].position );
bounds.extend( boundaryMarkers['1'].position );
map.fitBounds( bounds);
}
}
function mapOfEverything() {
if ( $('.map ').data('name') === 'everything' ) {
selectRegionBounds(); //to refresh boundaries on region select;
checkMapCategories(); //to display category filters for Map of Everything
}
}
function selectRegionBounds() {
$('.map-control .select').change( function(){
var region = $(this).find('option:selected').text();
refreshRegionBounds( region );
});
}
function refreshRegionBounds( regionName ) {
var regionBounds = new google.maps.LatLngBounds();
var regionNE, regionNW;
var regions = {
"West": [
[ 49.075306, -125.121097 ],
[ 31.514869, -103.148438 ]
],
"Rockies" : [
[ 48.960023, -117.166993 ],
[ 31.888753, -102.972657]
],
"Prairie" : [
[48.931162, -119.759766 ],
[ 31.627192, -89.349610 ]
],
"Northwest" : [
[71.485876, -171.421888],
[41.921898, -109.617194]
],
"Northeast" : [
[52.977754, -79.734381],
[ 38.500032, -52.136725]
],
"Mid South" : [
[39.592143, -106.628913],
[25.029865, -87.117194]
],
"Mid Atlantic" : [
[39.592143, -88.962897],
[24.471152, -73.845710]
],
"Great Lakes" : [
[57.529980, -95.466798],
[36.830391, -72.263673]
],
"Deep South" : [
[36.477842, -88.699220],
[24.950205, -75.427735]
],
"Centro" : [
[32.569038, -118.494147],
[9.475071, -60.398439]
]
};
if ( regions[regionName] ) {
regionNW = new google.maps.LatLng( regions[regionName]['0']['0'], regions[regionName]['0']['1'] );
regionNE = new google.maps.LatLng( regions[regionName]['1']['0'], regions[regionName]['1']['1']);
regionBounds.extend( regionNW );
regionBounds.extend( regionNE );
} else {
regionNW = new google.maps.LatLng( 72.743220, -171.632817 );
regionNE = new google.maps.LatLng( 2.565555, -53.507817 );
regionBounds.extend( regionNW );
regionBounds.extend( regionNE );
}
map.fitBounds( regionBounds );
}
function getLatLng( address ) {
var key = 'AIzaSyBDttorbDzy7Fa5IGeyvolnJZpiOVeQdBA';
var requestUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address='+address+'&key='+key;
var data;
$.ajax({
type: "GET",
url: requestUrl,
dataType: "json",
success: function (data) {
if ( data.results['0'] ) {
var addressLat = data.results['0'].geometry.location.lat;
var addressLng = data.results['0'].geometry.location.lng;
var formatted =data.results['0'].formatted_address;
data = [addressLat, addressLng];
setNewMapCenter( data );
updateAlert( formatted );
} else {
showMapWarning();
}
}
});
}
function getAddressFromLatLng( latlng ) {
var key = 'AIzaSyBDttorbDzy7Fa5IGeyvolnJZpiOVeQdBA';
var requestUrl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng='+latlng+'&key='+key;
var data;
$.ajax({
type: "GET",
url: requestUrl,
dataType: "json",
success: function (data) {
if ( data.results['0'] ) {
var formatted = data.results['0'].formatted_address;
return formatted;
}
}
});
}
function updateAlert( location ) {
$('.alert-info .location').text( location );
}
function showMapWarning( errorType ) {
var errors = {
'undefined': '',
};
return errors[errorType];
}
/* XML TO JSON */
// Changes XML to JSON
function xmlToJson(xml) {
// Create the return object
var obj = {};
if (xml.nodeType == 1) { // element
// do attributes
if (xml.attributes.length > 0) {
obj["@attributes"] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) { // text
obj = xml.nodeValue;
}
// do children
if (xml.hasChildNodes()) {
for(var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (typeof(obj[nodeName]) == "undefined") {
obj[nodeName] = xmlToJson(item);
} else {
if (typeof(obj[nodeName].push) == "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xmlToJson(item));
}
}
}
return obj;
}
function hasStorage(){
try{
localStorage.setItem('test', '7');
if(localStorage.getItem('test')=== '7'){
localStorage.removeItem('test');
return true;
}
}
catch(er){}
return false;
}
function loadStorage( key ){
if ( !key )
return false;
if ( key == 'mapCenterLatLng' && storageKey == 'single' ) {
mapCenterLatLng = {"lat": $('.map-single').data('lat'),"lng": $('.map-single').data('lng') };
saveStorage( 'mapCenterLatLng', mapCenterLatLng );
return mapCenterLatLng;
} else if ( key ) {
if ( localStorage.getItem( key ) === null || localStorage.getItem( key ) === undefined )
return false;
else if ( localStorage[ key ] === undefined )
return false;
else
return JSON.parse( localStorage.getItem( key ) );
} else {
//nothing
}
}
function saveStorage( key, obj ) {
var lastModified = Date.now();
var date_key = 'lastModified';
if ( key !== 'mapCenterLatLng' )
localStorage[ date_key ] = JSON.stringify( lastModified );
localStorage[ key ] = JSON.stringify(obj);
}
});