Jump to content

User:Evad37/GeoHack replacement script.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* Replace external links to GeoHack with direct links to a single mapping provider.
 *
 * It support the following replacement variables found in GeoHack:
 * {latdegdec} {londegdec} {scale} {span} {osmzoom}
 *
 * Based on a script by [[User:Dispenser]]: [[mw:GeoHack/Replacement_script]]
 *
- Instructions: add the following two lines to your common.js (or skin-specific js):

importScript('User:Evad37/GeoHack_replacement_script.js'); // [[User:Evad37/GeoHack_replacement_script.js]]
ghrs_mapprovider = "<url>";

- <url> is the url to load, specifiying the replacement variables above instead of actual values
- These urls can be found at [[Template:GeoTemplate]]
- For example, Google Maps:
ghrs_mapprovider = "http://maps.google.com/maps?ll={latdegdec},{londegdec}&spn={span},{span}&q={latdegdec},{londegdec}";
- or for OpenStreetMap:
ghrs_mapprovider = "http://www.openstreetmap.org/index.html?mlat={latdegdec}&mlon={londegdec}&zoom={osmzoom}&layers=B000FTF";
*/ 
jQuery( function( $ ) {
	if (window['ghrs_mapprovider'] === undefined) return;
 	var geohack_base = "//geohack.toolforge.org/geohack.php";
	var coord_filter = /[?&]params=([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([NSZ])_([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([EOW])([^&=]*)/;
	var replaceLinks = function ( $content ) {
		var link, lat, lon, scale;
		$content.find("a[href*='" + geohack_base + "']").each(function() {
			console.log("[replaceLinks] caption link href:", $(this).attr("href"));
			if(coord_filter.exec($(this).attr("href"))) {
				// latitude and longitude
				lat=(1.0*RegExp.$1) + ((RegExp.$2||0)/60.0) + ((RegExp.$3||0)/3600.0);
				if(RegExp.$4!='N') lat*=-1;
				lon=(1.0*RegExp.$5) + ((RegExp.$6||0)/60.0) + ((RegExp.$7||0)/3600.0);
				if(RegExp.$8=='W') lon*=-1;
				
				// Determine scale/zoom
				var params = RegExp.$9;
				if(/_globe:(?!earth|_|$)/i.test(params)) return;
				if(/_type:(adm3rd|city|mountain|isle|river|waterbody)/.test(params))scale = 100000;
				else if(/_type:(event|forest|glacier)/.test(params))scale = 50000;
				else if(/_type:(airport|edu|pass|landmark|railwaystation)/.test(params))scale = 10000;
				else scale = 300000;
				if(/_dim:([\d.+-]+)(km)?m?/.exec(params))scale = RegExp.$1 * (RegExp.$2?10000:10);
				if(/_scale:(\d+)(_|$)/.exec(params))scale = RegExp.$1;
				var osmzoom = 18 - Math.round(Math.log(scale/1693) / Math.log(2));
				var zoom =  Math.log( 1.5e8/scale) / Math.log(2);
				
				// Replace link
				var replacement_url = ghrs_mapprovider.replace(/\{latdegdec\}/g, lat).replace(/\{londegdec\}/g, lon).replace(/\{scale\}/g, scale).replace(/\{span\}/g, scale/1e6).replace(/\{osmzoom\}/g, osmzoom).replace(/\{zoom\}/g, zoom); 
				$(this).attr("href", replacement_url).parent().removeClass("plainlinks").parent().removeClass("plainlinks");
			}
		});
	};
	// Hook on to changes in page content, including initial load
	mw.hook('wikipage.content').add(replaceLinks);
	// Hook onto wikibase UI rendered (i.e. Wikidata mainspace)
	mw.hook('wikibase.entityPage.entityView.rendered').add(function() {
		// Coords statements have geohack links in kartographer map captions.
		// However, initially they are just plain text, and are made into a link
		// after a short delay. So for each caption, at intervals of 250ms, we
		// check if the link has appeared - until the link is found (and then we
		// can replace it), or until the 20th repition (to avoid infinite loop). 
		if ( !$(".wikibase-kartographer-caption").length ) { return; }
		$(".wikibase-kartographer-caption").each(function() {
			var interval,
				repitions = 0,
				context = this;
			interval = setInterval(function () {
				var $caption = $(context);
				if ( $caption.find("a").length ) {
					replaceLinks($caption);
					clearInterval(interval);
					return;
				}
				if (repitions === 20) {
					clearInterval(interval);
					return;
				}
				repitions++;
			}, 250);
		});
	});
});