Okay, itโs the day where gobsmacked readers of Earth Bearing Distance Missing Two Trip Compass Tutorial and (all) users of its โMissingTwoโ web application can be relieved of their โgobsmackederhoodโ?! Yes โฆ
- on top of our Wikipedia way to glean Latitude and Longitude for a Place Name โฆ today (oh, but the shame of it all, the shame, leaving it for so long โฆ
oh, the shame ofโokay, thatโs it โฆ pull yourself togetherโ) we finally get around to โฆ - โHereโ Place Name based HTML5 Geolocation API (should the user be allowing Location Services (into their frightfully busy lives) for their web browser of use) โฆ yayyyyyyyy!
โฆ is flagged to the user via that top textboxโs โplaceholderโ blurb being adjusted (for 7 seconds) as a user focuses there via changed HTML โฆ
<h1 id=myh1 style='display:block;'>Missing Two (<font size=1>optional</font> <span onclick="this.innerHTML=this.innerHTML.replace('to','From').replace('from','to').replace('From','from'); document.getElementById('ipn').focus(); " id=spfr title='Click me to toggle between from and to' style='cursor:pointer;'>from</span> <input onfocus='hereit(this,"");' title='Optionally semicolon separate an elevation affecting horizon distance used for Place Name/Bearing (where Compass app might show you this elevation value) input scenarios. Note that a Place Name/Distance scenario shows a Locality Distance Ring map. Append space for gyroscope bearing.' onblur='lkwk(this,"");' style='display:inline-block;width:280px;' placeholder='Place Name' id=ipn value='' type=text></input>) in Table Column <span data-onfocus="document.getElementById('semail').innerHTML='';" data-title='Email to (append a space to just show the table cell with the gradient)?' data-contenteditable=true data-onblur=preemail(this.innerHTML); onclick=emailit(''); id=semail title=Email>📧</span> <span data-onfocus="document.getElementById('semail').innerHTML='';" data-title='SMS to?' data-contenteditable=true data-onblur=preemail(this.innerHTML); onclick=toize(''); id=ssms title=SMS>📟</span><div id=dntable style=display:none;> <table border=1 id=ntable style="background-color:pink;display:inline-block;font-size:10px;"><tr><td>N</td></tr><tr><td>⬆</td></tr></table> <div style='display:inline-block;cursor:pointer;' id=arrowup title='To Portrait Up ... line up, parallel, with compass N to face North the ideal way' onclick='alert(this.title);'>⬆</div></div></h1>
โฆ calling on new Javascript โฆ
var oiqplaceholder='';
function oiqit() {
if (oiqplaceholder != '') {
hereit(document.getElementById('ipn'), oiqplaceholder);
oiqplaceholder='';
} else if (document.getElementById('ipn')) {
if (('' + document.getElementById('ipn').placeholder).indexOf('"Here" ') == 0 && ('' + document.getElementById('ipn').placeholder).indexOf(' Longitude. ') != -1) {
document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split(' Longitude. ')[1];
}
}
}
function hereit(oiq, twopis) {
var wasp='';
if (twopis != '') {
if (('' + oiq.placeholder).indexOf('"Here"') == -1) {
wasp=('' + oiq.placeholder);
oiq.placeholder='"Here" uses Geolocation derived Latitude, Longitude. ' + wasp;
setTimeout(oiqit, 7000);
}
document.getElementById('myh1').style.cursor='pointer';
} else if (oiq.value == '' && document.URL.toLowerCase().indexOf('https') == 0) {
if (('' + oiq.placeholder).indexOf('"Here"') == -1) {
wasp=('' + oiq.placeholder);
oiqplaceholder='"Here" uses Geolocation derived Latitude, Longitude. ' + wasp;
document.getElementById('myh1').style.cursor='progess';
setTimeout(oiqit, 500);
}
}
}
โฆ and if the user types in the Here we are looking for โฆ
function lkwk(oiis, twop) {
var doi=true;
if (oiis.value.trim() != '') {
if ((('' + oiis.value).replace(/\"/g,'').replace(/\'/g,'').replace(';',' ') + ' ').toLowerCase().indexOf('here ') == 0) { doi=false; if (1 == 2) { oiis.value=''; } doi=getLocation(); if (1 == 2) { return ''; } }
if (document.getElementById('tdmid')) {
if (document.getElementById('tdmid').innerHTML.toLowerCase().indexOf('<iframe') != -1) {
if (document.getElementById('spfr')) {
if (document.getElementById('spfr').innerHTML.toLowerCase().indexOf('rom') != -1) {
location.href=document.URL.split('#')[0].split('?')[0] + '?ipn=' + encodeURIComponent(oiis.value);
}
}
}
}
if (oiis.value.trim() != oiis.value) { tplacen=tplacen.trim(); } else { tplacen+=String.fromCharCode(32); }
var ois=oiis.value.trim().split(';');
if (doi) { document.getElementById('ifplacegeo').src=document.getElementById('ifplacegeo').src.split('?')[0].split('#')[0] + '?placegeo=' + encodeURIComponent(ois[0]); }
if (eval('' + ois.length) > 1) { elev=eval('' + ois[1]); evel=Math.max(elev, 2.0); }
if (twop == '') { oiis.value=''; }
if (doi) { document.body.style.cursor='progress'; }
}
}
โฆ new Geolocation API Javascript code swings into action โฆ
var userlatitude=0.0, userlongitude=0.0;
function getLocation() {
if (navigator.geolocation) {
try {
navigator.geolocation.getCurrentPosition(showPosition);
//setTimeout(later, 1000);
return false;
} catch(err) {
//setTimeout(later, 1000);
}
} else if (userlatitude != 0.0 || userlongitude != 0.0) {
//document.getElementById('you').innerHTML='(0,0)';
if (document.getElementById('spfr').innerHTML.indexOf('rom') != -1) {
if (document.getElementById('latf') && document.getElementById('longf')) {
document.getElementById('latf').focus();
document.getElementById('latf').value=userlatitude;
document.getElementById('longf').focus();
document.getElementById('longf').value=userlongitude;
document.getElementById('latf').focus();
userlatitude=0.0;
userlongitude=0.0;
document.getElementById('ssf').innerHTML='Here';
gllentry='' + document.getElementById('latf').value + ',' + document.getElementById('longf').value + ',Here';
askit();
//document.getElementById('spfr').innerHTML='to';
fplacen='Here';
return false;
}
} else {
if (document.getElementById('latt') && document.getElementById('longt')) {
document.getElementById('latt').focus();
document.getElementById('latt').value=userlatitude;
document.getElementById('longt').focus();
document.getElementById('longt').value=userlongitude;
document.getElementById('latt').focus();
userlatitude=0.0;
userlongitude=0.0;
document.getElementById('sst').innerHTML='Here';
gllentry='' + document.getElementById('latt').value + ',' + document.getElementById('longt').value + ',Here';
askit();
tplacen='Here';
return false;
}
}
}
return true;
}
function showPosition(position) {
if (userlatitude == 0.0 && userlongitude == 0.0) {
userlatitude=eval('' + position.coords.latitude);
userlongitude=eval('' + position.coords.longitude);
if (userlatitude != 0.0 || userlongitude != 0.0) {
//document.getElementById('you').innerHTML='(0,0)';
if (document.getElementById('spfr').innerHTML.indexOf('rom') != -1) {
if (document.getElementById('latf') && document.getElementById('longf')) {
document.getElementById('latf').focus();
document.getElementById('latf').value=userlatitude;
document.getElementById('longf').focus();
document.getElementById('longf').value=userlongitude;
document.getElementById('latf').focus();
userlatitude=0.0;
userlongitude=0.0;
document.getElementById('ssf').innerHTML='Here';
gllentry='' + document.getElementById('latf').value + ',' + document.getElementById('longf').value + ',Here';
askit();
//document.getElementById('spfr').innerHTML='to';
fplacen='Here';
}
} else {
if (document.getElementById('latt') && document.getElementById('longt')) {
document.getElementById('latt').focus();
document.getElementById('latt').value=userlatitude;
document.getElementById('longt').focus();
document.getElementById('longt').value=userlongitude;
document.getElementById('latt').focus();
userlatitude=0.0;
userlongitude=0.0;
document.getElementById('sst').innerHTML='Here';
gllentry='' + document.getElementById('latt').value + ',' + document.getElementById('longt').value + ',Here';
askit();
tplacen='Here';
}
}
}
}
}
โฆ into ourchanged missing_twohtmlโs โMissing
Twoโ web application.
What a programmerโs relief!
Previous relevant Earth Bearing Distance Missing Two Trip Compass Tutorial is shown below.
The recent Earth Bearing Distance Missing Two Trip North Point Tutorial set up a โฆ
- mobile device โNorth pointโ additional functionality โฆ and today โฆ
- more compass use helpers to guide user towards facing North โฆ as well as โฆ
- allow for Degrees Minutes Seconds as alternative angular method of entry harnessing changed HTML โฆ exemplified by โฆ
Latitude (decimal degrees): <input title='' style='width:90px;display:inline-block;' onchange='this.style.backgroundColor="pink";cwhat[0]=false; cwhat[1]=false; if (!decided) { if (!cwhat[5]) { cwhat[5]=true; } if (!cwhat[4]) { cwhat[4]=true; } decided=true; } top.document.getElementById("ltf").value=this.value; ' onblur='this.style.backgroundColor="pink"; cwhat[0]=false; cwhat[1]=false; if (!decided) { if (!cwhat[5]) { cwhat[5]=true; } if (!cwhat[4]) { cwhat[4]=true; } decided=true; } top.document.getElementById("ltf").value=mdms(this.value,this); ' id=latf name=latf type=number onfocus='ati=0; atic=[]; atis=[];' onkeydown='couldbedms(event);' min=-90.0000000 max=90.0000000 step=0.0000010 value='0.0000000'></input><br>
โฆ helped out by new Javascript โฆ
var ati=0, atis=[], atic=[];
function mdms(tvis, otvis) {
var altvl=0.0, dvr=1.0, isv=0;
if (eval('' + atic.length) >= 1) {
//alert('ov=' + otvis.value + ' and atic[0]=' + atic[0]);
if (atic[0].indexOf('-') != -1 && otvis.value.indexOf('-') == -1) {
isv++;
} else if (atic[0].indexOf('+') != -1 && otvis.value.indexOf('+') == -1) {
isv++;
} else if (eval('' + atis.length) >= 2) {
if (eval('' + atis[1]) > 60) { isv++; }
}
}
if (eval('' + atic.length) > 1) {
//alert('Here ' + atic.length + ' last is=' + atic[eval(-1 + atic.length)]);
for (var ijh=0; ijh<atic.length; ijh++) {
if (atic[ijh].trim() != '') {
isv++;
if (atic[0].indexOf('-') != -1) {
altvl-=eval(eval('' + dvr) * eval(atic[ijh].replace('-','')));
} else {
altvl+=eval(eval('' + dvr) * eval(atic[ijh].replace('-','')));
}
//alert('Here ' + altvl);
dvr/=60.0;
}
}
if (isv > 1) {
tvis='' + altvl;
otvis.value='' + altvl;
}
}
ati=0;
atic=[];
atis=[];
return tvis;
}
function idms(otvis) {
var altvl=0.0, dvr=1.0, isv=0;
if (eval('' + atic.length) >= 1) {
//alert('Ov=' + otvis.value + ' and Atic[0]=' + atic[0]);
if (atic[0].indexOf('-') != -1 && otvis.value.indexOf('-') == -1) {
isv++;
} else if (atic[0].indexOf('+') != -1 && otvis.value.indexOf('+') == -1) {
isv++;
} else if (eval('' + atis.length) >= 2) {
if (eval('' + atis[1]) > 60) { isv++; }
}
}
if (eval('' + atic.length) > 1) {
//alert('here ' + atic.length + ' last is=' + atic[eval(-1 + atic.length)]);
for (var ijh=0; ijh<atic.length; ijh++) {
if (atic[ijh].trim() != '') {
isv++;
if (atic[0].indexOf('-') != -1) {
altvl-=eval(eval('' + dvr) * eval(atic[ijh].replace('-','').replace('+','')));
} else {
altvl+=eval(eval('' + dvr) * eval(atic[ijh].replace('-','').replace('+','')));
}
//alert('here ' + altvl);
dvr/=60.0;
}
}
if (isv > 1) {
otvis.value='' + altvl;
}
}
ati=0;
atic=[];
atis=[];
return otvis;
}
function couldbedms(event) {
var wasc='';
if (eval('' + event.keyCode) == 69 || eval('' + event.keyCode) == 78 || eval('' + event.keyCode) == 87 || eval('' + event.keyCode) == 83 || eval('' + event.keyCode) == 187 || eval('' + event.keyCode) == 189 || eval('' + event.keyCode) == 190 || (eval('' + event.keyCode) >= 48 && eval('' + event.keyCode) <= 57)) {
if (ati == 0) { atis=[]; atis.push(0); atic.push(''); } else if (ati < 0) { ati=0; }
ati++;
atis[eval(-1 + atis.length)]=ati;
if (eval('' + event.keyCode) == 87 || eval('' + event.keyCode) == 83) {
if (atic[0].indexOf('-') == -1) { wasc=atic[0]; atic[0]='-' + wasc; }
} else if (eval('' + event.keyCode) == 69 || eval('' + event.keyCode) == 78) {
if (atic[0].indexOf('+') == -1) { wasc=atic[0]; atic[0]='+' + wasc; }
} else if (eval('' + event.keyCode) != 187) {
atic[eval(-1 + atic.length)]+=String.fromCharCode(eval(eval('' + event.keyCode) % 144));
}
} else {
ati=-1;
if (eval('' + event.keyCode) >= 65 && eval('' + event.keyCode) <= 90) {
atis.push(eval('' + event.keyCode));
} else {
atis.push(0);
}
atic.push('');
}
}
โฆ improving the functionality and ease of use of ourchanged missing_twohtmlโs โMissing
Twoโ web application when using a mobile platform.
Previous relevant Earth Bearing Distance Missing Two Trip North Point Tutorial is shown below.
We build on the recent Earth Bearing Distance Missing Two Trip Tap Orientation Tutorial and help out those โwhatโs out there in the distanceโ dreamers of Earth Bearing Distance Missing Two Trip Details Orientation Tutorial by, today adding a โNorth pointโ (HTML table element) to โฆ
- todayโschanged missing_two
htmlโs Missing
Two live run that is affected, but two other web applications as per โฆ
- todayโschanged yaw_etc
htmlโs Device
Orientation live run โฆ and โฆ
โฆ on some mobile platforms, such as the iOS iPad we tested, adding compass like new functionality, as per the new HTML โฆ
<h1 id=myh1 style='display:block;'>Missing Two (<font size=1>optional</font> <span onclick="this.innerHTML=this.innerHTML.replace('to','From').replace('from','to').replace('From','from'); document.getElementById('ipn').focus(); " id=spfr title='Click me to toggle between from and to' style='cursor:pointer;'>from</span> <input title='Optionally semicolon separate an elevation affecting horizon distance used for Place Name/Bearing (where Compass app might show you this elevation value) input scenarios. Note that a Place Name/Distance scenario shows a Locality Distance Ring map. Append space for gyroscope bearing.' onblur='lkwk(this);' style='display:inline-block;width:280px;' placeholder='Place Name' id=ipn value='' type=text></input>) in Table Column <span data-onfocus="document.getElementById('semail').innerHTML='';" data-title='Email to (append a space to just show the table cell with the gradient)?' data-contenteditable=true data-onblur=preemail(this.innerHTML); onclick=emailit(''); id=semail title=Email>📧</span> <span data-onfocus="document.getElementById('semail').innerHTML='';" data-title='SMS to?' data-contenteditable=true data-onblur=preemail(this.innerHTML); onclick=toize(''); id=ssms title=SMS>📟</span><div id=dntable style=display:none;> <table border=1 id=ntable style="background-color:pink;display:inline-block;font-size:10px;"><tr><td>N</td></tr><tr><td>⬆</td></tr></table> ⬆</div></h1>
โฆ and Javascript โฆ
var wasthisso='' + (screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type); //"portrait";
var wasangle=eval(180 - eval('' + window.orientation));
if (1 == 1) {
window.addEventListener("orientationchange", function() {
// Announce the new orientation number
wasangle=eval(180 - eval('' + window.orientation));
var thisso='' + screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type;
if (('' + thisso) == 'undefined') {
var mql=window.matchMedia("(orientation: portrait)");
// If there are matches, we're in portrait
if (mql.matches) {
thisso="Portrait"; // Portrait orientation
} else {
thisso="Landscape"; // Landscape orientation
}
}
if (thisso != wasthisso) {
wasthisso=thisso;
//alert('ori');
}
}, false);
}
if (window.DeviceOrientationEvent) {
if (1 == 2) { alert(1); }
// Listen for orientation changes ... thanks to https://davidwalsh.name/orientation-change
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
// gamma is the left-to-right tilt in degrees, where right is positive
if (1 == 2) { alert(11); }
if (document.getElementById('ipn')) {
//if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and face north for gyroscope bearing.') == -1) {
if (('' + document.getElementById('ipn').placeholder).indexOf(' and ') == -1) {
document.getElementById('ipn').className='ph';
document.getElementById('ipn').placeholder+='. Append space and portrait face north for gyroscope bearing.';
document.getElementById("myviewport").setAttribute("content", "width=device-width, initial-scale=1.5, minimum-scale=0.1, maximum-scale=8, user-scalable=yes");
setTimeout(asafn, 5000);
}
}
//eventData.absolute=true;
var eventDataalpha = eval(360.0 - eval('' + eventData.alpha)); // lalpha)); //
if (eventData.absolute !== true && +eventData.webkitCompassAccuracy > 0 && +eventData.webkitCompassAccuracy < 50) {
eventDataalpha = eval('' + eventData.webkitCompassHeading || 0);
if (document.getElementById('dntable')) { document.getElementById('dntable').style.display='inline-block'; }
}
if (!datstart) { eventDataalpha-=initial_yaw; }
tiltLeftToRight = eval('' + eventData.gamma);
// beta is the front-to-back tilt in degrees, where front is positive
tiltFrontToBack = eval('' + eventData.beta);
// alpha is the compass direction the device is facing in degrees
lastalpha='' + eventData.alpha; // lalpha; //
dorbrg = eval('' + eventDataalpha); //compassHeading(eval('' + eventDataalpha), tiltFrontToBack, tiltLeftToRight);
if (1 == 2) { alert(dorbrg); }
if (document.URL.indexOf('aleJUNKrt=') != -1) {
alert(dorbrg);
}
if (document.URL.indexOf('upJUNKdate=') != -1 || (fplacen != '' && tplacen == '')) {
if (eventData.absolute || 1 == 1) {
//document.getElementById('brg').value='' + eval(eval(540.0 - eval('' + dorbrg)) % 360.0);
//document.getElementById('brg').value='' + eval(eval(720.0 - eval('' + dorbrg)) % 360.0);
//document.getElementById('brg').value='' + dorbrg;
if (eval(dcnt % 10) == 0) {
document.getElementById('brg').value='' + eval(eval(720.0 + eval('' + dorbrg)) % 360.0);
document.getElementById('brg').style.backgroundColor='yellow';
}
dcnt++;
}
}
if (datstart && (fplacen != '' && tplacen == '')) {
datstart=false;
//initial_yaw=eval(360.0 - eval('' + lalpha)); //eventData.alpha));
//alert('0:' + initial_yaw);
if (!eventData.absolute) {
initial_yaw=eval(360.0 - eval('' + eventData.alpha)); // lalpha)); //
}
//alert('' + initial_yaw);
initial_pitch=Math.round(tiltFrontToBack);
initial_roll=Math.round(tiltLeftToRight);
//alert(initial_yaw + ',' + initial_pitch + ',' + initial_roll);
}
if (document.getElementById('ntable')) {
var ts=450;
if (wasangle != 0) {
ts+=wasangle;
}
try { document.getElementById('ntable').style.webkitTransform = ("rotate(" + eval(ts - Math.round(dorbrg)) + "deg)"); } catch(e10) { }
try { document.getElementById('ntable').style.MozTransform = ("rotate(" + eval(ts - Math.round(dorbrg)) + "deg)"); } catch(e1000) { }
try { document.getElementById('ntable').style.msTransform = ("rotate(" + eval(ts - Math.round(dorbrg)) + "deg)"); } catch(e100) { }
try { document.getElementById('ntable').style.OTransform = ("rotate(" + eval(ts - Math.round(dorbrg)) + "deg)"); } catch(e10000) { }
try { document.getElementById('ntable').style.transform = ("rotate(" + eval(ts - Math.round(dorbrg)) + "deg)"); } catch(e1) { }
}
handleOrientationEvent(tiltFrontToBack, tiltLeftToRight, dorbrg, eventData.absolute);
if ((fplacen != '' && tplacen == '') && document.getElementById('ipn')) {
//if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and face north for gyroscope bearing.') != -1) {
if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and ') != -1) {
document.getElementById('ipn').style.backgroundColor='#f0f0f0';
//document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split('Append space and face north for gyroscope bearing.')[0] + ' Now swivel to direction of interest then tap yellow textbox.';
document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split('Append space and ')[0] + ' Now swivel to direction of interest then tap yellow textbox.';
document.getElementById("myviewport").setAttribute("content", "width=device-width, initial-scale=1.2, minimum-scale=0.1, maximum-scale=8, user-scalable=yes");
//window.scrollBy(0,50); //location.href='#brg';
}
}
}, false);
}
Previous relevant Earth Bearing Distance Missing Two Trip Tap Orientation Tutorial is shown below.
That window.DeviceOrientationEvent event work of the recent Earth Bearing Distance Missing Two Trip Details Orientation Tutorial was missing an important point. We learnt about this point by debugging on an iOS (iPhone 7) Google Chrome web browser, as we showed with yesterdayโs Google Chrome on iOS Web Browser Debug Tutorial. That tutorialโs finding lead us to the Google search for โฆ
ERROR NotAllowedError Requesting device
โฆ and onto the excellent How to requestPermission for devicemotion and deviceorientation events in iOS 13+ โฆ
One more thing
One more thing to keep in mind is that requestPermission could only be called on a user gesture (e.g. click). This is reasonable UX too as we would want to tell users why we are asking for such permissions and let them confirm before prompting them so that they see it coming.
Otherwise you would get this error:
Console error: NotAllowedError: Requesting device orientation or motion access requires a user gesture to prompt
โฆ where we needed to shift our oft-used document.body onload event code placement thinking to allow for this thinking, plus the provision of a button for the user to tap, as required, should the โpermissionโ popup window be required to seek permission to, effectively, access that deviceโs gyroscope measurements via that window.DeviceOrientationEvent and/or window.DeviceMotionEvent event(s).
This is a similar Apple requirement, as it applies to iOS playing audio files, which we have mentioned quite a bit at this blog. One could say โฆ
We should have known.
โฆ and luckily two is too polite to say โฆ
You blockhead!
โฆ to which we are infinitely grateful, and will install for the rest of the day, that โฆ
Two is our favourite number (for the rest of today, that is).
But itโs not only โฆ
- todayโschanged missing_two
htmlโs Missing
Two live run that is affected, but two other web applications as per โฆ
- todayโschanged yaw_etc
htmlโs Device
Orientation live run โฆ and โฆ
- todayโschanged simon_says
htmlโs Simon
Says live run
โฆ for you to try for yourself, perhaps there on your mobile device with an accessible gyroscope on a compatible web browser such as Google Chrome (or others, now) on iOS.
Previous relevant Earth Bearing Distance Missing Two Trip Details Orientation Tutorial is shown below.
Humans, particularly before the advent of the mobile devices, were probably (as a whole) more skilled regarding navigation via โlandmarksโ or โsunmarksโ or โmoonmarksโ working out โฆ
In which direction is North?
Well, the irony here, today, is that the better you have been hanging onto these skills you are, the better you can use our new โฆ
- mobile phone โฆ
- containing a gyroscope โฆ but โฆ
- not an accessible compass (or if so, the knowledge of where North is becomes superfluous below) โฆ
- using a compatible web browser such as Google Chrome โฆ
- a good indication your scenario is compatible being that at some stage you answer โAllowโ to a prompt as below โฆ
โฆ at some point โฆ using โฆ - todayโschanged missing_two
htmlโs live
run link modifications โฆ using โฆ
- window.DeviceOrientationEvent event โฆ and perhaps you could use โฆ
- window.DeviceMotionEvent event
โฆ
- software detection to offer that user โฆ
โฆ the chance to mix technology with human navigational instincts to answer that perennial question similarly asked in Earth Bearing Distance Missing Two Place Name and Horizon Tutorial โฆ
Whatโs out there in the distance?
โฆ via โฆ
- using a compatible web browser such as Google Chrome โฆ live
run โฆ
- point your mobile phone in portrait to North (or at least arrange to do this just before tapping the Done link in step below) โฆ
- enter in a Place Name into that top textbox (to which, itโs good, as known, to append semicolon elevation) and add a space, and because you are on a mobile device, tap the Done link
- bearing text will start being updated with bearing of your mobile device portrait mode top pointing direction โฆ so โฆ
- when youโve swivelled the mobile device to be pointing (in portrait) to the (Whatโs out there in the distance?) direction of interest, tap that yellow bearing textbox, then tap the Done link โฆ resulting in โฆ
- Google Chart Map Chart showing your Place Name and (the calculated) Horizon Position in that direction of your choosing
โฆ meaning the combination of โฆ
- your mobile deviceโs gyroscopeโs angle measuring talent (akin to those theodolite talents Land Surveyors are using) โฆ and โฆ
- your navigational talents knowing where North is
โฆ save you having to know that awkward โbearingโ (in degrees) textbox answer to Whatโs out there in the distance? Perhaps see what we mean viewing todayโs animated GIF presentation.
Onto yesterdayโs Earth Bearing Distance Missing Two Trip Details Styling Tutorial and since the last time we ventured into the wooooorrrrrlllldddd of โwindow.DeviceOrientationEventโ logic weโve gotten great help Javascript coding for the permissions side to the handling of this event, as per โฆ
if ((navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) || document.URL.indexOf('alert=') != -1) && document.URL.toLowerCase().indexOf('https:') != 0) {
location.href=document.URL.replace('http:','https:') + '&random=' + Math.floor(Math.random() * 174765654);
}
if ((navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) || document.URL.indexOf('update=') != -1) && document.URL.toLowerCase().indexOf('https:') != 0) {
location.href=document.URL.replace('http:','https:') + '&random=' + Math.floor(Math.random() * 174765654);
}
// Thanks to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await and
// https://gist.github.com/Ajasra/ddd616505013a4309c0dda8a8ba626cb
async function myfunction() {
console.log('Inside of myfunction');
//alert(0);
if (window.DeviceOrientationEvent && typeof(DeviceOrientationEvent.requestPermission) === "function") {
//alert(4);
const permissionState = await DeviceOrientationEvent.requestPermission().then(response => {
if (response === 'granted') {
if (1 == 2) { alert('GrAnted'); }
//window.addEventListener('deviceorientation', OrientationHandler, true);
dorh();
} else if (result.state === 'prompt') {
if (1 == 2) { alert("Need prompt!"); }
} else {
if (1 == 2) { alert("Not Supported!"); }
}
}).catch(console.error);
//if (permissionState === "granted") {
// alert('granted');
//} else {
// alert('denied');
//}
} else if (window.DeviceOrientationEvent) {
//alert(44);
dorh();
}
if (window.DeviceMotionEvent && typeof(DeviceMotionEvent.requestPermission) === "function") {
//alert(24);
const permissionStateM = await DeviceMotionEvent.requestPermission().then(response => {
if (response === 'granted') {
if (1 == 2) { alert('GranTed'); }
window.addEventListener('devicemotion', function(event) {
lalpha='' + event.rotationRate.alpha;
});
//window.addEventListener('deviceorientation', OrientationHandler, true);
} else if (result.state === 'prompt') {
if (1 == 2) { alert("NeeD prompt!"); }
} else {
if (1 == 2) { alert("NoT Supported!"); }
}
}).catch(console.error);
//if (permissionStateM === "granted") {
// alert('Granted');
//} else {
// alert('Denied');
//}
} else if (window.DeviceMotionEvent) {
//alert(244);
window.addEventListener('devicemotion', function(event) {
lalpha='' + event.rotationRate.alpha;
});
}
}
// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later
// Also point that we don't use async keyword on the function because
// we can simply returns the promise returned by myfunction
function start() {
return myfunction();
}
// Call start
(async() => {
console.log('before start');
await start();
console.log('after start');
})();
var degtorad = Math.PI / 180; // Degree-to-Radian conversion ... thanks to https://www.w3.org/TR/orientation-event/#worked-example
function dorh() {
//let laSensor = new LinearAccelerationSensor({frequency: 60});
//laSensor.addEventListener('reading', e => {
// console.log("Linear acceleration along the X-axis " + laSensor.x);
// console.log("Linear acceleration along the Y-axis " + laSensor.y);
// console.log("Linear acceleration along the Z-axis " + laSensor.z);
//});
//laSensor.start();
//window.addEventListener('devicemotion', function(event) {
// alert(event.rotationRate.alpha + ' m/s2');
//});
if (1 == 3) {
window.addEventListener("orientationchange", function() {
// Announce the new orientation number
var thisso='' + screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type;
if (('' + thisso) == 'undefined') {
var mql=window.matchMedia("(orientation: portrait)");
// If there are matches, we're in portrait
if (mql.matches) {
thisso="Portrait"; // Portrait orientation
} else {
thisso="Landscape"; // Landscape orientation
}
}
if (thisso != wasthisso) {
wasthisso=thisso;
alert('ori');
}
}, false);
}
if (window.DeviceOrientationEvent) {
if (1 == 2) { alert(1); }
// Listen for orientation changes ... thanks to https://davidwalsh.name/orientation-change
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
// gamma is the left-to-right tilt in degrees, where right is positive
if (1 == 2) { alert(11); }
if (document.getElementById('ipn')) {
//if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and face north for gyroscope bearing.') == -1) {
if (('' + document.getElementById('ipn').placeholder).indexOf(' and ') == -1) {
document.getElementById('ipn').className='ph';
document.getElementById('ipn').placeholder+='. Append space and portrait face north for gyroscope bearing.';
document.getElementById("myviewport").setAttribute("content", "width=device-width, initial-scale=1.5, minimum-scale=0.1, maximum-scale=8, user-scalable=yes");
setTimeout(asafn, 5000);
}
}
//eventData.absolute=true;
var eventDataalpha = eval(360.0 - eval('' + eventData.alpha)); // lalpha)); //
if (!datstart) { eventDataalpha-=initial_yaw; }
tiltLeftToRight = eval('' + eventData.gamma);
// beta is the front-to-back tilt in degrees, where front is positive
tiltFrontToBack = eval('' + eventData.beta);
// alpha is the compass direction the device is facing in degrees
lastalpha='' + eventData.alpha; // lalpha; //
dorbrg = eval('' + eventDataalpha); //compassHeading(eval('' + eventDataalpha), tiltFrontToBack, tiltLeftToRight);
if (1 == 2) { alert(dorbrg); }
if (document.URL.indexOf('aleJUNKrt=') != -1) {
alert(dorbrg);
}
if (document.URL.indexOf('upJUNKdate=') != -1 || (fplacen != '' && tplacen == '')) {
if (eventData.absolute || 1 == 1) {
//document.getElementById('brg').value='' + eval(eval(540.0 - eval('' + dorbrg)) % 360.0);
//document.getElementById('brg').value='' + eval(eval(720.0 - eval('' + dorbrg)) % 360.0);
//document.getElementById('brg').value='' + dorbrg;
if (eval(dcnt % 10) == 0) {
document.getElementById('brg').value='' + eval(eval(720.0 + eval('' + dorbrg)) % 360.0);
document.getElementById('brg').style.backgroundColor='yellow';
}
dcnt++;
}
}
if (datstart && (fplacen != '' && tplacen == '')) {
datstart=false;
//initial_yaw=eval(360.0 - eval('' + lalpha)); //eventData.alpha));
//alert('0:' + initial_yaw);
if (!eventData.absolute) {
initial_yaw=eval(360.0 - eval('' + eventData.alpha)); // lalpha)); //
}
//alert('' + initial_yaw);
initial_pitch=Math.round(tiltFrontToBack);
initial_roll=Math.round(tiltLeftToRight);
//alert(initial_yaw + ',' + initial_pitch + ',' + initial_roll);
}
handleOrientationEvent(tiltFrontToBack, tiltLeftToRight, dorbrg, eventData.absolute);
if ((fplacen != '' && tplacen == '') && document.getElementById('ipn')) {
//if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and face north for gyroscope bearing.') != -1) {
if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and ') != -1) {
document.getElementById('ipn').style.backgroundColor='#f0f0f0';
//document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split('Append space and face north for gyroscope bearing.')[0] + ' Now swivel to direction of interest then tap yellow textbox.';
document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split('Append space and ')[0] + ' Now swivel to direction of interest then tap yellow textbox.';
document.getElementById("myviewport").setAttribute("content", "width=device-width, initial-scale=1.2, minimum-scale=0.1, maximum-scale=8, user-scalable=yes");
//window.scrollBy(0,50); //location.href='#brg';
}
}
}, false);
}
}
var handleOrientationEvent = function(tiltFrontToBack, tiltLeftToRight, dorbrg, absis) {
// do something amazing
if (1 == 2) { alert(dorbrg); }
if (document.URL.indexOf('alJUNKert=') != -1) {
alert(dorbrg);
}
if (document.URL.indexOf('upJUNKdate=') != -1 || (fplacen != '' && tplacen == '')) {
if (absis || 1 == 1) {
//document.getElementById('brg').value='' + eval(eval(540.0 - eval('' + dorbrg)) % 360.0);
//document.getElementById('brg').value='' + eval(eval(720.0 - eval('' + dorbrg)) % 360.0);
//document.getElementById('brg').value='' + dorbrg;
if (eval(dcnt % 10) == 0) {
document.getElementById('brg').value='' + eval(eval(720.0 + eval('' + dorbrg)) % 360.0);
document.getElementById('brg').style.backgroundColor='yellow';
}
dcnt++;
}
}
};
function asafn() {
if (document.getElementById('ipn')) {
//if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and face north for gyroscope bearing.') == -1) {
if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and portrait face north for ') != -1) {
document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split('Append space and ')[0] + 'Append space and portrait face north onto ;elevation(m)?';
setTimeout(asafn, 5000);
} else if (('' + document.getElementById('ipn').placeholder).indexOf('Append space and ') != -1) {
document.getElementById('ipn').placeholder=document.getElementById('ipn').placeholder.split('Append space and ')[0] + 'Append space and portrait face north for horizon bearing.';
setTimeout(asafn, 5000);
}
}
}
Today we added a meta viewport, and for the first time that we can recall, we started styling the โplaceholderโ of that top textbox as per (thanks to https://stackoverflow.com/questions/44679144/how-to-make-input-placeholder-font-size-different-from-input-value-font-size) โฆ
<meta id="myviewport" name="viewport" content="width=device-width, initial-scale=1, minimum-scale=0.1, maximum-scale=8, user-scalable=yes" >
<style>
summary { background-color: #f0f0f0; }
.ph::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: red;
opacity: 1; /* Firefox */
font-size: 8px;
}
.ph:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: red;
font-size: 8px;
}
.ph::-ms-input-placeholder { /* Microsoft Edge */
color: red;
font-size: 8px;
}
</style>
Previous relevant Earth Bearing Distance Missing Two Trip Details Styling Tutorial is shown below.
On top of the recent Earth Bearing Distance Missing Two Trip Details Reveal Tutorial, today we discuss styling strategies a little. When and where do you style your webpage? We think you do it all along, but for us, we like โlittle spurtsโ at it too, so we might let a web application project progress in a practical approach not worrying about aesthetics too much until we do a โlittle spurtโ bubble of activity regarding styling. Often times ideas for that can be developed away from the laptop you might write the code on. For example, todayโschanged missing_twohtmlโs live
run link modifications were directed by an email we sent to ourselves โฆ
Jobs
Robert Metcalfe
Sun, Sep 12, 8:16 PM (5 days ago)
to me
Vertical-align: top
I frame too high
To after horizon leaves horizon I frame title
Lat long display online-block
Coloured summary background colour
Th header cells text-align center
Sent from my iPhone
โฆ โmind mapโ type ideas that may or may not be followed through to fruition, depending on โฆ
- where possible
- where feasible
- where wise
This strategy above is for your small projects, else if much bigger, or involving multiple people to produce, or being written to a specification, or being written for a third party, youโd be much better placed to think about styling issues from the start, in a plan. You might want to use wireframes?
On these small projects we also donโt mind just involving the one HTML (or PHP writing HTML) source file and use a combination of โฆ
- inline <style> CSS styling goes here </style> within the webpage <head></head> header section โฆ or โฆ
- in amongst the HTML via โstyleโ attribute โฆ eg. <p id=โmypโ style=โ CSS styling for p element goes here โ> Content for p element goes here </p>
โฆ or Javascript DOM code such as โฆ
document.getElementById('myp').style.fontSize='18px';
โฆ and it is very rare, with these small projects, though very good in organizational terms, to write all your CSS styling in an external CSS (styling file) arrangement such as โฆ
<head>
<link href='./my_styling.css' rel='stylesheet' type='text/css'>
</head>
There are many ways to โฆ well, you know what I mean โฆ a cat! Not only were โno cats harmed in the making of this tutorialโ but no cats were even roughed up?!
Previous relevant Earth Bearing Distance Missing Two Trip Details Reveal Tutorial is shown below.
Yes, thereโs only so long you can use the wonderful details/summary HTML element combination as with the recent Earth Bearing Distance Missing Two Trip Details Summary Tutorialโs โฆ
we often use to โrevealโ, or not, webpage โreal estateโ, but today we default to the โopenโ look
โฆ just using that โopenโ element mode of use, and not want to make use of its โrevealโ talents. How so? Well, a bit like the dropdown element, we find that the details/summary combination allows for the containment of lots of data for a controlled amount of โrevealโ. In this day and age of responsiveness to limited screen sizes, that is a big advantage.
Today, then, with ourchanged missing_twohtmlโs live
run link, we have โฆ
- that first (at first) โopenโ details/summary nesting a Google Chart Map Chart iframe summarizing the entirety of your Trip โฆ today โฆ
- festooned with up arrow emoji (
) โbuttonโ links which, when clicked, zero in (into a new topmost โonly openโ details/summary nesting Google Chart Map Chart iframe set of data) on any one โlegโ of your trip, displaying its own crow fly distance and Google Maps Directions information link, as well as new โฆ
- accommodation (
) links ala accommodation in Springwood, New South Wales Google image search style links
โฆ to enhance a Trip Plannerโs user experience. Perhaps best to explain a bit codewise is to say โfollow the Javascript variable interesting in code belowโ โฆ
function askit() {
var ourdist=0.0, ourbrg=0.0;
//alert(gllentry);
if (gllentry.indexOf(',') != -1) {
if ((1 == 2 && gllonesuffix == 'f') || document.getElementById('spfr').innerHTML == 'from') {
tpurl=origtpurl;
document.getElementById('latf').focus();
document.getElementById('latf').value=gllentry.split(',')[0];
//var mu="//www.rjmprogramming.com.au/PHP/Map/map.php?title=London&label=['Lat',&value='Lon','Name']&data=,[51.5072,-0.1275,~London~]";
mu=mu.replace('[51.5072,','[' + gllentry.split(',')[0] + ',');
document.getElementById('longf').focus();
document.getElementById('longf').value=gllentry.split(',')[1];
mu=mu.replace(',-0.1275,',',' + gllentry.split(',')[1] + ',');
document.getElementById('latf').focus();
gllonesuffix = 't';
document.getElementById('spfr').innerHTML=document.getElementById('spfr').innerHTML.replace('from','to<input type=hidden name=fplacen value="' + gllentry.split(',')[2].replace(/\;/g,',') + '"></input>');
fplacen=gllentry.split(',')[2].replace(/\;/g,',');
document.getElementById('ssf').innerHTML=' ' + gllentry.split(',')[2].replace(/\;/g,',');
mu=mu.replace('=LonJunkdon','=' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,','))).replace(',~London~]',',~' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')) + '~],[051.5072,-00.1275,~LonDon~]');
tpurl=tpurl.replace("Sydney+NSW,+Australia",encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')));
if (document.getElementById('sftif') && document.getElementById('iftif')) {
document.getElementById('iftif').src=document.getElementById('iftif').src.replace('&',encodeURIComponent(' from ' + gllentry.split(',')[2].replace(/\;/g,',')) + '&') + ',[' + gllentry.replace(',' + gllentry.split(',')[1] + ',', ',' + gllentry.split(',')[1] + ',~').replace(/\ /g,'%20') + '~]';
document.getElementById('sftif').innerHTML+=' <a target=_blank title=Accomodation onclick=woit(this); data-href="' + accomurl.replace(/Springwood\,\+New\+South\+Wales/g, encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')).replace(/\%20/g,'+')) + '">from 🛌</a> <a target=_blank title="' + gllentry.split(',')[2].replace(/\;/g,',') + '" href="//en.wikipedia.org/wiki/' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')) + '">' + gllentry.split(',')[2].replace(/\;/g,',') + '</a>';
document.getElementById('brg').value='0.0000000';
document.getElementById('dist').value='0.000';
document.getElementById('brg').style.backgroundColor='white';
document.getElementById('dist').style.backgroundColor='white';
cwhat=[false,false,true,true,false,false];
ourdist=great_circle_distance(document.getElementById(eles[0]).value,document.getElementById(eles[1]).value,document.getElementById(eles[4]).value,document.getElementById(eles[5]).value);
document.getElementById(eles[3]).value='' + ourdist;
//Let โRโ be the radius of Earth,
//โLโ be the longitude,
//โฮธโ be latitude,
//โฮฒโ be Bearing.
//Bearing from point A to B, can be calculated as,
//ฮฒ = atan2(X,Y),
//where, X and Y are two quantities and can be calculated as:
//X = cos ฮธb * sin โL
//Y = cos ฮธa * sin ฮธb โ sin ฮธa * cos ฮธb * cos โL
ourbrg=eval(eval(360.0 + eval(eval(eval(180.0 / Math.PI) * Math.atan2(
eval(eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value))) *
eval('' + Math.sin(eval(Math.PI / 180.0) * eval(eval('' + document.getElementById(eles[5]).value) - eval('' + document.getElementById(eles[1]).value))))),
eval(eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value))) *
eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value)))) -
eval(eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value))) *
eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value))) *
eval('' + Math.cos(eval(Math.PI / 180.0) * eval(eval('' + document.getElementById(eles[5]).value) - eval('' + document.getElementById(eles[1]).value)))))
)))) % 360.0);
document.getElementById('mysel').value='2';
document.getElementById(eles[2]).value='' + ourbrg;
document.getElementById(eles[2]).style.backgroundColor='lightgreen';
document.getElementById(eles[3]).style.backgroundColor='lightgreen';
}
} else {
var interesting=false, waslatt='', waslongt='', wasfplacen='';
if (gllonesuffix == 'f') {
interesting=true;
waslatt=document.getElementById('latt').value;
waslongt=document.getElementById('longt').value;
if (documentURL == document.URL) {
wasfplacen=location.search.split('tplacen=')[1] ? (' ' + decodeURIComponent(location.search.split('tplacen=')[1].split('&')[0]).replace(/\+/g,' ')) : ''; //document.getElementById('tplacen').value;
} else {
wasfplacen=decodeURIComponent(documentURL.split('tplacen=')[eval(-1 + documentURL.split('tplacen=').length)].split('&')[0]);
}
//alert('interesting');
}
mu=mu.replace('=London','=' + encodeURIComponent(fplacen));
document.getElementById('brg').focus();
document.getElementById('dist').focus();
document.getElementById('latt').focus();
document.getElementById('latt').value=gllentry.split(',')[0];
mu=mu.replace('[051.5072,','[' + gllentry.split(',')[0] + ',');
document.getElementById('longt').focus();
document.getElementById('longt').value=gllentry.split(',')[1];
mu=mu.replace(',-00.1275,',',' + gllentry.split(',')[1] + ',');
document.getElementById('latt').focus();
gllonesuffix = 'f';
if (interesting) {
document.getElementById('spfr').innerHTML=document.getElementById('spfr').innerHTML.replace('to','from<input type=hidden id=tplacen name=tplacen value="' + gllentry.split(',')[2].replace(/\;/g,',') + '"></input>');
} else {
document.getElementById('spfr').innerHTML=document.getElementById('spfr').innerHTML.replace('to','from<input type=hidden id=tplacen name=tplacen value="' + gllentry.split(',')[2].replace(/\;/g,',') + '"></input>');
}
document.getElementById('ifill').value='Map Trip';
document.getElementById('sst').innerHTML=' ' + gllentry.split(',')[2].replace(/\;/g,',');
mu=mu.replace(',~LonDon~]',',~' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')) + '~]');
tpurl=tpurl.replace("Brisbane+QLD,+Australia",encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')));
if (document.getElementById('sftif') && document.getElementById('iftif')) {
if (document.getElementById('addafirst')) { document.getElementById('addafirst').style.display='inline-block'; }
if (document.getElementById('addacc')) { document.getElementById('addacc').style.display='inline-block'; }
document.getElementById('iftif').src=document.getElementById('iftif').src.replace('&',encodeURIComponent(' to ' + gllentry.split(',')[2].replace(/\;/g,',')) + '&') + ',[' + gllentry.replace(',' + gllentry.split(',')[1] + ',', ',' + gllentry.split(',')[1] + ',~').replace(/\ /g,'%20') + '~]';
//if (interesting) {
// alert('interesting ... fplacen=' + fplacen);
//}
if (interesting) {
document.getElementById('sftif').innerHTML+=(' from <a target=_blank title="' + wasfplacen + '" href="//en.wikipedia.org/wiki/' + encodeURIComponent(wasfplacen) + '">' + wasfplacen + '</a> ').substring(0,1) + '<a target=_blank title=Accomodation onclick=woit(this); data-href="' + accomurl.replace(/Springwood\,\+New\+South\+Wales/g, encodeURIComponent(wasfplacen).replace(/\%20/g,'+')) + '">🛌</a>' + '<a target=_blank title="Google Maps Directions" href="' + tpurl.replace('https:','') + '">to</a><a title="Map of this trip leg" class="adda" onclick="addto(this);" data-from="' + (wasfplacen ? wasfplacen : fplacen) + '" data-to="' + gllentry.split(',')[2].replace(/\;/g,',') + '" style="display:inline-block;cursor:pointer;" data-latf=' + (waslatt ? waslatt : document.getElementById('latf').value) + ' data-longf=' + (waslongt ? waslongt : document.getElementById('longf').value) + ' data-latt=' + document.getElementById('latt').value + ' data-longt=' + document.getElementById('longt').value + ' data-gcd=' + eval(eval('' + great_circle_distance((waslatt ? waslatt : document.getElementById(eles[0]).value),(waslongt ? waslongt : document.getElementById(eles[1]).value),document.getElementById(eles[4]).value,document.getElementById(eles[5]).value)) / 1000.000) + '>⬆<a> <a target=_blank title="' + gllentry.split(',')[2].replace(/\;/g,',') + '" href="//en.wikipedia.org/wiki/' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')) + '">' + gllentry.split(',')[2].replace(/\;/g,',') + '</a> (' + '<a target=_blank title=Accomodation onclick=woit(this); data-href="' + accomurl.replace(/Springwood\,\+New\+South\+Wales/g, encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')).replace(/\%20/g,'+')) + '">🛌</a> ' + eval(eval('' + great_circle_distance(document.getElementById(eles[0]).value,document.getElementById(eles[1]).value,document.getElementById(eles[4]).value,document.getElementById(eles[5]).value)) / 1000.000) + ' kilometres)';
//alert('interesting ... fplacen=' + wasfplacen);
} else {
document.getElementById('sftif').innerHTML+=' <a target=_blank title="Google Maps Directions" href="' + tpurl.replace('https:','') + '">to</a><a title="Map of this trip leg" class="adda" onclick="addto(this);" data-from="' + (wasfplacen ? wasfplacen : fplacen) + '" data-to="' + gllentry.split(',')[2].replace(/\;/g,',') + '" style="display:inline-block;cursor:pointer;" data-latf=' + (waslatf ? waslatf : document.getElementById('latf').value) + ' data-longf=' + (waslongf ? waslongf : document.getElementById('longf').value) + ' data-latt=' + document.getElementById('latt').value + ' data-longt=' + document.getElementById('longt').value + ' data-gcd=' + eval(eval('' + great_circle_distance((waslatf ? waslatf : document.getElementById(eles[0]).value),(waslongf ? waslongf : document.getElementById(eles[1]).value),document.getElementById(eles[4]).value,document.getElementById(eles[5]).value)) / 1000.000) + '>⬆<a> <a target=_blank title="' + gllentry.split(',')[2].replace(/\;/g,',') + '" href="//en.wikipedia.org/wiki/' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')) + '">' + gllentry.split(',')[2].replace(/\;/g,',') + '</a> (' + '<a target=_blank title=Accomodation onclick=woit(this); data-href="' + accomurl.replace(/Springwood\,\+New\+South\+Wales/g, encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,',')).replace(/\%20/g,'+')) + '">🛌</a> ' + eval(eval('' + great_circle_distance(document.getElementById(eles[0]).value,document.getElementById(eles[1]).value,document.getElementById(eles[4]).value,document.getElementById(eles[5]).value)) / 1000.000) + ' kilometres)';
}
document.getElementById('brg').style.backgroundColor='white';
document.getElementById('dist').style.backgroundColor='white';
documentURL+='&tplacen=' + encodeURIComponent(gllentry.split(',')[2].replace(/\;/g,','));
cwhat=[false,false,true,true,false,false];
ourdist=great_circle_distance(document.getElementById(eles[0]).value,document.getElementById(eles[1]).value,document.getElementById(eles[4]).value,document.getElementById(eles[5]).value);
document.getElementById(eles[3]).value='' + ourdist;
//Let โRโ be the radius of Earth,
//โLโ be the longitude,
//โฮธโ be latitude,
//โฮฒโ be Bearing.
//Bearing from point A to B, can be calculated as,
//ฮฒ = atan2(X,Y),
//where, X and Y are two quantities and can be calculated as:
//X = cos ฮธb * sin โL
//Y = cos ฮธa * sin ฮธb โ sin ฮธa * cos ฮธb * cos โL
ourbrg=eval(eval(360.0 + eval(eval(eval(180.0 / Math.PI) * Math.atan2(
eval(eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value))) *
eval('' + Math.sin(eval(Math.PI / 180.0) * eval(eval('' + document.getElementById(eles[5]).value) - eval('' + document.getElementById(eles[1]).value))))),
eval(eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value))) *
eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value)))) -
eval(eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value))) *
eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value))) *
eval('' + Math.cos(eval(Math.PI / 180.0) * eval(eval('' + document.getElementById(eles[5]).value) - eval('' + document.getElementById(eles[1]).value)))))
)))) % 360.0);
document.getElementById('mysel').value='2';
document.getElementById(eles[2]).value='' + ourbrg;
document.getElementById(eles[2]).style.backgroundColor='lightgreen';
document.getElementById(eles[3]).style.backgroundColor='lightgreen';
if (interesting) {
document.getElementById('spfr').innerHTML='to';
document.getElementById('ipn').focus();
}
}
}
document.getElementById('ipn').placeholder=gllentry.split(',')[2].replace(/\;/g,',');
}
gllentry='';
document.getElementById('placegeo').value='';
}
Previous relevant Earth Bearing Distance Missing Two Trip Details Summary Tutorial is shown below.
The recent Earth Bearing Distance Missing Two Locality Distance Ring Tutorial coalesced โFromโ Place name functionality for โฆ
- defined bearing โฆ deriving horizon place
- defined distance โฆ deriving ring of positions โฆ and today we consider โฆ
- Trip functionality thoughts via โToโ Place name definitions supplementing the already entered โFromโ Place name
We say โTrip Details Summaryโ in our blog posting title today as a hint about how we present a nester of Google Chart Map Chart display data.
The details/summary HTML element combination we often use to โrevealโ, or not, webpage โreal estateโ, but today we default to the โopenโ look and add Wikipedia links and crowfly distance and Google Maps Directions information into the summary tag, for extra interest with your Trip planning.
The user can access this functionality with ourchanged missing_twohtmlโs live
run link โฆ
- user enters โFromโ Place Name via new textbox โฆ eg. โLawson, New South Walesโ
- user enters โToโ Place Name via new textbox โฆ eg. โKatoombaโ
- user clicks/taps the โFillโ button
- optionally the user can add more places to the Map Chart by adding more โFromโ and/or โToโ Place Name definitions
Previous relevant Earth Bearing Distance Missing Two Locality Distance Ring Tutorial is shown below.
The corollary to yesterdayโs Earth Bearing Distance Missing Two Place Name and Horizon Tutorialโs โฆ
- locality and bearing derivation of a โplace on horizonโ position โฆ is, today โฆ
- locality and distance derivation of a โlocality distance ringโ set of positions
โฆ again, combining the geodata talents of Wikipedia and a Google Chart Map Chart, we figure.
And so a user accessing this functionality with ourchanged missing_twohtmlโs live
run link โฆ
- user enters โFromโ Place Name via new textbox โฆ eg. โLawson, New South Walesโ
- user enters โDistanceโ (eg. โ5000.000โ metres) and tabs out โฆ we use the โonblurโ event โฆ
var dok=true;
function dfillablemaybe(brgo) {
if (!dok) { return ''; }
var i, ourbrg=0.0, ourdist=0.0, j, dvlat='', dvlong='';
if (('' + brgo.value).replace(/0/g,'').replace('.','') != '') {
//alert('356:' + document.getElementById('dist').value);
if (('' + document.getElementById('dist').value).replace(/0/g,'').replace('.','') == '' || (fplacen != '' && tplacen == '')) {
//alert(456);
if (('' + document.getElementById('latt').value).replace(/0/g,'').replace('.','') == '' || (fplacen != '' && tplacen == '')) {
//alert(556);
if (('' + document.getElementById('longt').value).replace(/0/g,'').replace('.','') == '' || (fplacen != '' && tplacen == '')) {
//alert(656);
if (('' + document.getElementById('ssf').innerHTML) != '') {
//alert(756);
if (!viastart) {
//document.getElementById('brg').focus();
document.getElementById('brg').value='0.0000001';
//brgo.focus();
}
if (mu.indexOf('[051.5072,') != -1) {
//alert(856);
if (!viastart) {
//alert(1);
document.getElementById('ifill').click();
//alert(11);
}
mu=mu.replace('[051.5072,','[' + eval('' + document.getElementById('latt').value).toFixed(3) + ',');
mu=mu.replace(',-00.1275,',',' + eval('' + document.getElementById('longt').value).toFixed(3) + ',');
if (('' + brgo.value).indexOf('000.000') != -1) {
//mu=mu.replace(encodeURIComponent('looking out North'), encodeURIComponent(('' + brgo.value).split('000.000')[0] + 'km Ring'));
mu=mu.replace(',~LonDon~]',',~' + encodeURIComponent(fplacen + ' looking North') + '~]');
mu=mu.replace('=London','=' + encodeURIComponent(fplacen + (' ' + brgo.value).split('000.000')[0] + 'km Ring'));
} else {
mu=mu.replace(',~LonDon~]',',~' + encodeURIComponent(fplacen + ' looking North') + '~]');
mu=mu.replace('=London','=' + encodeURIComponent(fplacen + ' looking out North'));
}
//mu=mu.replace(',~LonDon~]',',~' + encodeURIComponent(fplacen + ' looking North') + '~]');
//mu=mu.replace('=London','=' + encodeURIComponent(fplacen + ' looking out North'));
//alert('956:' + mu);
//document.getElementById('hplacen').innerHTML='<input type=hidden name=fplacen value="' + mu + '"></input>';
//document.getElementById('tdmid').innerHTML='<iframe src="' + mu + '" style="width:100%;height:700px;"></iframe>';
if (viastart) {
for (var dbrg=30; dbrg<=330; dbrg+=30) {
//document.getElementById('brg').value='' + dbrg + '.0000000';
if (('' + document.getElementById('mysel').value) == '2') {
ourbrg=eval(eval(540.0 + 180.0 + eval('' + document.getElementById(eles[2]).value)) % 360.0);
} else {
ourbrg=eval('' + document.getElementById(eles[2]).value);
}
ourbrg=eval('' + dbrg);
for (j=eval(3 - eval(('' + document.getElementById('mysel').value))); j>=1; j--) {
ourdist=eval('' + document.getElementById(eles[3]).value);
//Let first point latitude be la1,
///longitude as lo1,
//d be distance,
//R as radius of Earth,
//Ad be the angular distance i.e d/R and.
//ฮธ be the bearing,
//Here is the formula to find the second point, when first point, bearing and distance is known:
//latitude of second point = la2 = asin(sin la1 * cos Ad + cos la1 * sin Ad * cos ฮธ), and
//longitude of second point = lo2 = lo1 + atan2(sin ฮธ * sin Ad * cos la1 , cos Ad โ sin la1 * sin la2)
dvlat='' +
eval(eval(eval(180.0 / Math.PI) * Math.asin(
Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value)) *
Math.cos(eval(eval('' + ourdist) / 6371000.0)) +
Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value)) *
Math.sin(eval(eval('' + ourdist) / 6371000.0)) *
Math.cos(eval(Math.PI / 180.0) * eval('' + ourbrg)))));
//Let first point latitude be la1,
//longitude as lo1,
//d be distance,
//R as radius of Earth,
//Ad be the angular distance i.e d/R and
//ฮธ be the bearing,
// longitude of second point = lo2 = lo1 + atan2(sin ฮธ * sin Ad * cos la1 , cos Ad โ sin la1 * sin la2)
dvlong='' + eval(eval(180.0 / Math.PI) * eval(eval(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[1]).value)) +
Math.atan2(
eval(eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + ourbrg)) *
eval('' + Math.sin(eval(eval('' + ourdist) / 6371000.0)))) *
eval('' + Math.cos(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value)))),
eval(eval('' + Math.cos(eval(eval('' + ourdist) / 6371000.0))) -
eval(eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[0]).value)))) *
eval('' + Math.sin(eval(Math.PI / 180.0) * eval('' + document.getElementById(eles[4]).value)))))));
mu+=',[' + eval('' + dvlat).toFixed(3) + ',' + eval('' + dvlong).toFixed(3) + ',~' + dbrg + '~]';
}
}
document.getElementById('tdmid').innerHTML='<iframe src="' + mu + '" style="width:100%;height:700px;"></iframe>';
fplacen='';
}
}
}
}
}
}
}
}
โฆ logic of that occurrence to say it is this scenario and above โฆ so โฆ - set bearing to value โ0.0000001โ (ie. start the locality distance ring looking North)
- we programmatically click the yellow โFillโ button
- a Google Chart Map Chart is displayed with both โฆ
- observer position โฆ and this approximate calculated โฆ
- locality distance ring set of positions at 30 degree intervals around the ring whose radius is the Distance value (in metres) entered by the user
Previous relevant Earth Bearing Distance Missing Two Place Name and Horizon Tutorial is shown below.
Yesterdayโs Earth Bearing Distance Missing Two Place Name Tutorial left off with โฆ
We hope so, and there is another reason for this preparatory work that will be explained tomorrow. Stay tuned!
Well, todayโs โtomorrowโ. Let me ask first, did you read our Compass iOS App Primer Tutorial? Well, the use of the Compass iOS (and am sure Android would have their own version of) mobile app fits into our scenario whereby โฆ
- we had occasion to be looking at a long distance view into the distance down a road both โฆ
- during the day โฆ and also seeing โฆ
- lights at night
โฆ which set us (being of the โwhere are weโ looking curious set) wondering โฆ
- where are we looking?
- whipping out the iPhoneโs Compass app gave us all of โฆ
- bearing to distant view โฆ
- elevation in metres โฆ interesting โฆ
- latitude, longitude of where we were (though we think weโll get help from Wikipedia here, thanks)
โฆ meaning โฆ
- we could offer the user of ourchanged missing_two
htmlโs live
run link the chance to involve data items 1 and 2 above directly and 3 (via Wikipedia) โฆ to have it that โฆ
- user enters โFromโ Place Name via new textbox (and add the Compass app elevation (in metres) as a semicolon separated data item) โฆ eg. โLawson, New South Wales;740โ
- user enters โBearingโ (eg. โ185โ (off the Compass app)) and tabs out โฆ we use the โonblurโ event โฆ
var dok=true;
function fillablemaybe(brgo) {
if (('' + brgo.value).replace(/0/g,'').replace('.','') != '') {
//alert('356:' + document.getElementById('dist').value);
if (('' + document.getElementById('dist').value).replace(/0/g,'').replace('.','') == '' || (fplacen != '' && tplacen == '')) {
//alert(456);
if (('' + document.getElementById('latt').value).replace(/0/g,'').replace('.','') == '' || (fplacen != '' && tplacen == '')) {
//alert(556);
if (('' + document.getElementById('longt').value).replace(/0/g,'').replace('.','') == '' || (fplacen != '' && tplacen == '')) {
//alert(656);
if (('' + document.getElementById('ssf').innerHTML) != '') {
//alert(756);
if (!viastart) {
dok=false;
document.getElementById('dist').focus();
if (1 == 1) { // assume 2m elevation ... thanks to https://en.wikipedia.org/wiki/Horizon
document.getElementById('dist').value='' + Math.floor(Math.pow(eval(eval(2.0 * eval('' + elev)) * 6371000.0), 0.5)) + '.000';
} else {
document.getElementById('dist').value='5000.000';
}
elev=2.0;
brgo.focus();
}
if (mu.indexOf('[051.5072,') != -1) {
//alert(856);
if (!viastart) {
document.getElementById('ifill').click();
}
mu=mu.replace('[051.5072,','[' + document.getElementById('latt').value + ',');
mu=mu.replace(',-00.1275,',',' + document.getElementById('longt').value + ',');
mu=mu.replace(',~LonDon~]',',~' + encodeURIComponent(fplacen + ' looking out at bearing ' + brgo.value + ' degrees towards horizon') + '~]');
mu=mu.replace('=London','=' + encodeURIComponent(fplacen + ' looking out at bearing ' + brgo.value + ' degrees towards horizon'));
//alert('956:' + mu);
//document.getElementById('hplacen').innerHTML='<input type=hidden name=fplacen value="' + mu + '"></input>';
document.getElementById('tdmid').innerHTML='<iframe src="' + mu + '" style="width:100%;height:700px;"></iframe>';
if (viastart) {
fplacen='';
}
}
}
}
}
}
}
}
โฆ logic of that occurrence to say it is this scenario and above โฆ so compute โฆ - the distance to horizon is computed via square root of two times elevation (in meters) times radius of earth (in meters) โฆ then โฆ
- we programmatically click the yellow โFillโ button
- a Google Chart Map Chart is displayed with both โฆ
- observer position โฆ and this approximate calculated โฆ
- horizon position
โฆ to help you un-nut โwhere are we looking?โ โฆ we hope
โฆ which you can see the gist of with todayโs animated GIF presentation.
Bit like relaxed orienteering, would you say?!
Previous relevant Earth Bearing Distance Missing Two Place Name Tutorial is shown below.
Itโs often a good news story in I.T. when you can replace or supplement numbers with names (without being too nosy about it, that is!) And so, extending the functionality of our โMissing Twoโ web application talked about, last, with Earth Bearing Distance Missing Two Trip Share Tutorial we allow the user to enter in Place Names as an alternative to entering in the Latitude and Longitude co-ordinates of that placeโs position on the earth, especially apt for any web application purporting to be helpful regarding โtripโ functionality.
Being suckers for โthe where of lifeโ web applications out there, weโre tickled pink to be offering this โred zoneโ special extension to functionality, and all because you asked for it (well, thatโs my story, and am sticking with it).
As we went along coding for this change, and implications of this into the future, we realized we needed to allow for two more (GET argument) data items to be catered for, the codelines below responsible for โreading them inโ โฆ
var fplacen=location.search.split('fplacen=')[1] ? (' ' + decodeURIComponent(location.search.split('fplacen=')[1].split('&')[0]).replace(/\+/g,' ')) : '';
var tplacen=location.search.split('tplacen=')[1] ? (' ' + decodeURIComponent(location.search.split('tplacen=')[1].split('&')[0]).replace(/\+/g,' ')) : '';
โฆ and allowed for within the (static) HTMLโs form elementโs HTML as per โฆ
<h1 id=myh1 style='display:block;'>Missing Two (<font size=1>optional</font> <span id=spfr>from</span> <input onblur='lkwk(this);' style='display:inline-block;' placeholder='Place Name' id=ipn value='' type=text></input>) in a Table Column <span data-onfocus="document.getElementById('semail').innerHTML='';" data-title='Email to (append a space to just show the table cell with the gradient)?' data-contenteditable=true data-onblur=preemail(this.innerHTML); onclick=emailit(''); id=semail title=Email>📧</span> <span data-onfocus="document.getElementById('semail').innerHTML='';" data-title='SMS to?' data-contenteditable=true data-onblur=preemail(this.innerHTML); onclick=toize(''); id=ssms title=SMS>📟</span></h1>
โฆ and โฆ
<tr id=trhead style='display:table-row;'><th style='width:30%;text-align:left;background-color:#f0e0d0;'><a title='Show nearest TimeZone places' id=afrom onclick=mapit(this); style='cursor:pointer;text-decoration:underline;'>From</a><span id=ssf></span>> <div id=dfrom style='display:none;'></div></th><th style='width:30%;text-align:left;background-color:#e0d0f0;'> ... On The Way ...</th><th style='text-align:left;background-color:#d0f0e0;'><a title='Show nearest TimeZone places' id=ato onclick=mapit(this); style='cursor:pointer;text-decoration:underline;'>To</a><span id=sst></span> <div id=dto style='display:none;'></div></th></tr>
โฆ and populated via supportive โonloadโ event based Javascript DOM โWikipedia (thanks) basedโ logic as per โฆ
if (fplacen != '') {
document.getElementById('ssf').innerHTML=fplacen;
fplacen='';
}
if (tplacen != '') {
document.getElementById('sst').innerHTML=tplacen;
tplacen='';
}
โฆ as the incoming code paradigm, living with the outgoing paradigmโs work based on that โlkwk(this);โ Javascript function โฆ
var gllentry='';
function askit() {
//alert(gllentry);
if (gllentry.indexOf(',') != -1) {
if (gllonesuffix == 'f') {
document.getElementById('latf').focus();
document.getElementById('latf').value=gllentry.split(',')[0];
document.getElementById('longf').focus();
document.getElementById('longf').value=gllentry.split(',')[1];
document.getElementById('latf').focus();
gllonesuffix = 't';
document.getElementById('spfr').innerHTML=document.getElementById('spfr').innerHTML.replace('from','to<input type=hidden name=fplacen value="' + gllentry.split(',')[2].replace(/\;/g,',') + '"></input>');
document.getElementById('ssf').innerHTML=' ' + gllentry.split(',')[2].replace(/\;/g,',');
} else {
document.getElementById('brg').focus();
document.getElementById('dist').focus();
document.getElementById('latt').focus();
document.getElementById('latt').value=gllentry.split(',')[0];
document.getElementById('longt').focus();
document.getElementById('longt').value=gllentry.split(',')[1];
document.getElementById('latt').focus();
gllonesuffix = 'f';
document.getElementById('spfr').innerHTML=document.getElementById('spfr').innerHTML.replace('to','from<input type=hidden name=tplacen value="' + gllentry.split(',')[2].replace(/\;/g,',') + '"></input>');
document.getElementById('sst').innerHTML=' ' + gllentry.split(',')[2].replace(/\;/g,',');
}
document.getElementById('ipn').placeholder=gllentry.split(',')[2].replace(/\;/g,',');
}
gllentry='';
document.getElementById('placegeo').value='';
}
function lookforg() {
if (document.getElementById('placegeo').value != '') {
gllentry=document.getElementById('placegeo').value + ',' + decodeURIComponent(document.getElementById('ifplacegeo').src.split('?placegeo=')[1]).replace(/\,/g,';');
askit();
} else {
setTimeout(lookforg,1000);
}
}
function checkit(iois) {
if (iois != null) {
if (iois.src.indexOf('?placegeo=') != -1) {
//alert(1);
var aconto = (iois.contentWindow || iois.contentDocument);
//alert(11);
if (aconto != null) {
//alert(111);
if (aconto.document) { aconto = aconto.document; }
//alert(1111);
if (aconto.body != null) {
//alert(2);
document.body.style.cursor='pointer';
if (document.getElementById('placegeo').value != '') {
//alert(3);
gllentry=document.getElementById('placegeo').value + ',' + decodeURIComponent(iois.src.split('?placegeo=')[1]).replace(/\,/g,';');
askit();
} else {
//alert(8);
setTimeout(lookforg,1000);
}
}
}
}
}
}
function lkwk(oiis) {
if (oiis.value.trim() != '') {
document.getElementById('ifplacegeo').src=document.getElementById('ifplacegeo').src.split('?')[0].split('#')[0] + '?placegeo=' + encodeURIComponent(oiis.value);
oiis.value='';
document.body.style.cursor='progress';
}
}
โฆ supporting the relevant (new static) HTML โฆ
<iframe onload='checkit(this);' style='display:none;' id=ifplacegeo src='../PHP/fgc/index.php'></iframe>
<input type=hidden id=placegeo value=''></input>
Believe it or not, with this web application, it is important what input type=text textboxes are โvisitedโ, and up until today, we had no concerns with that โorderingโ issue very much, because we only coded for โreal userโ interactive input, but todayโs place name functionality modifications mean that we feel we need to programmatically force the order somewhat in these place name entry scenarios, but we were not sure whether our non-mobile only (and slightly kludgy feeling) [input type=text element].focus(); interventions would/could work. But they did, happily, at least for non-mobile platforms! This means input type=text element โonblurโ events must have been triggered, we figure, which is an interesting finding (well, you had to be there, didnโt you?!)
Perhaps, then, thechanged missing_twohtmlโs live
run link will spark your interest? We hope so, and there is another reason for this preparatory work that will be explained tomorrow. Stay tuned!
Previous relevant Earth Bearing Distance Missing Two Trip Share Tutorial is shown below.
When Ajax came on the scene, HTML form navigation got that bit daggier. But as time has gone on, weโve started appreciating those more traditional HTML form navigation methodologies more for a few major reasons โฆ
- the FormData in the Ajax/FormData combination of navigational methodologies simulates static HTML form element functionality
- weโve grown to really admire โInline HTML Emailโ sharing via PHP mail to the email and back again out to the โwwwโ wooooorrrrrlllllddd via an โInline HTML Email Formโ (as widens the scope of use for todayโs web application)
- weโve grown to really admire a static HTML form elementโs โonsubmitโ event to massage an HTML form elementโs content on the way through to accepting the โactionโ form navigational destination, or reject that
- weโve grown to really admire the concept of multiple submit button elements without or with an associated name attribute to be able to detect which submit button was clicked/touched
โฆ and it seems to me there are now in the web application wooooorrrrrllllddd a plethora of navigational functionality choices for programmers out there. Yayyyyy!
And so, onto Earth Bearing Distance Missing Two Trip Tutorial today we add two sharing conduit โฆ
- SMS
โฆ means of functionality which call on โฆ
function preemailit(ine) {
if (ine.indexOf('@') != -1) {
emailit(ine);
} else if (ine != '') {
toize(ine);
}
}
function dummyencodeURIComponent(invl) {
return invl;
}
function emailit(defe) {
//document.getElementById('ih').value=document.getElementById('tdlook').innerHTML.replace(/\<br\>/g,String.fromCharCode(10));
var lastfis='youllneverfindthis';
var lasttis='';
var lasteis='youllneverfindthis';
var lastenow='';
var lastsis='youllneverfindthis';
var lastsnow='';
var lasteis2='youllneverfindthis';
var lastenow2='';
var lastsis2='youllneverfindthis';
var lastsnow2='';
var em='';
var suffbits='?latf=' + encodeURIComponent(document.getElementById('latf').value) + '&longf=' + encodeURIComponent(document.getElementById('longf').value) + '&latt=' + encodeURIComponent(document.getElementById('latt').value) + '&longt=' + encodeURIComponent(document.getElementById('longt').value) + '&brg=' + encodeURIComponent(document.getElementById('brg').value) + '&dist=' + encodeURIComponent(document.getElementById('dist').value);
if (defe.indexOf('@') != -1) {
em=defe
} else {
em=prompt('Email to? (all uppercase uses client email else sends an Inline HTML Email Form)', '');
}
if (em == null) { em=''; }
if (em.indexOf('@') != -1) {
//document.getElementById('from').value=em;
if (document.URL.toLowerCase().indexOf('rjmprogramming.com.au') != -1 && em != em.toUpperCase()) {
var xzhr = new XMLHttpRequest();
var xform=new FormData();
xform.append('inline','');
xform.append('to',em.trim());
var flatf=document.getElementById('latf').outerHTML;
var flongf=document.getElementById('longf').outerHTML;
var flatt=document.getElementById('latt').outerHTML;
var flongt=document.getElementById('longt').outerHTML;
var fbrg=document.getElementById('brg').outerHTML;
var fdist=document.getElementById('dist').outerHTML;
var tlatf='<input type=text name=latf id=latf value="' + document.getElementById('latf').value + '"></input>';
var tlongf='<input type=text name=longf id=longf value="' + document.getElementById('longf').value + '"></input>';
var tlatt='<input type=text name=latt id=latt value="' + document.getElementById('latt').value + '"></input>';
var tlongt='<input type=text name=longt id=longt value="' + document.getElementById('longt').value + '"></input>';
var tbrg='<input type=text name=brg id=brg value="' + document.getElementById('brg').value + '"></input>';
var tdist='<input type=text name=dist id=dist value="' + document.getElementById('dist').value + '"></input>';
//if (from.indexOf('@') != -1) { xform.append('cc',from.trim()); }
console.log('tdfrom');
faux=true;
mapit(document.getElementById('tdfrom'));
console.log(document.getElementById('afrom').href);
console.log('tdto');
faux=true;
mapit(document.getElementById('tdto'));
console.log(document.getElementById('ato').href);
if (document.body.innerHTML.indexOf('<tr id="trfoot"') != -1) {
lastfis='<tr id="trfoot"' + document.body.innerHTML.split('<tr id="trfoot"')[1].split('</tr>')[0] + '</tr>';
if (document.getElementById('asms').href.indexOf('sms:') != -1) {
lasteis='<span ';
lastenow='<a target=_blank href="mailto:?subject=' + dummyencodeURIComponent(encodeURIComponent('Missing%20Two')) + '&body=' + dummyencodeURIComponent(encodeURIComponent(document.getElementById('asms').href.split('&body=')[1])) + '" ';
lasteis2='</span>';
lastenow2='</a>';
lastsis='<span ';
lastsnow='<a target=_blank href="' + document.getElementById('asms').href.split('&')[0] + '&body=' + dummyencodeURIComponent(encodeURIComponent(document.getElementById('asms').href.split('&body=')[1])) + '" ';
lastsis2='</span>';
lastsnow2='</a>';
} else if (document.getElementById('asms').href.indexOf('mailto:') != -1) {
lastsis='<span ';
lastsis=document.getElementById('ssms').outerHTML.split('>')[0] + '>';
lastsnow='<a target=_blank href="sms:&body=' + dummyencodeURIComponent(encodeURIComponent(document.getElementById('asms').href.split('&body=')[1])) + '" ';
lastsnow='<input type=submit title=SMS name=sms id=ssms value="';
lastsis2='</span>';
lastsnow2='</a>';
lastsnow2='"></input>';
lasteis='<span ';
lastenow='<a target=_blank href="mailto:' + em.trim() + '?subject=' + dummyencodeURIComponent(encodeURIComponent('Missing%20Two')) + '&body=' + dummyencodeURIComponent(encodeURIComponent(document.getElementById('asms').href.split('&body=')[1])) + '" ';
lasteis2='</span>';
lastenow2='</a>';
}
}
if (em.trim() != em) {
xform.append('subj','Missing Two');
//var cbgtd=document.getElementById('tdlook').getBoundingClientRect();
xform.append('body','<body>' + document.body.innerHTML.replace(/\ id\=\"mysel\"/g, ' name="mysel" id="mysel"').replace(/\ size\=\"3\"/g, ' size="4"').replace(/\ data\-href\=/g, ' target=_blank href=').replace('</form>', '<br><br><input style=background-color:lightgreen; type=submit value=Solve></input></form>').replace('DISPLAY:table-row','DISPLAY:none').replace(lastfis,lasttis).replace(lasteis,lastenow).replace(lasteis2,lastenow2).replace(lastsis,lastsnow).replace(lastsis2,lastsnow2).replace('absolute;','absolute;display:none;').replace(flatf,tlatf).replace(flongf,tlongf).replace(flatt,tlatt).replace(flongt,tlongt).replace(fbrg,tbrg).replace(fdist,tdist) + '</body>');
} else {
xform.append('subj','Missing Two');
xform.append('body','<body>' + document.body.innerHTML.replace(/\ id\=\"mysel\"/g, ' name="mysel" id="mysel"').replace(/\ size\=\"3\"/g, ' size="4"').replace(/\ data\-href\=/g, ' target=_blank href=').replace('</form>', '<br><br><input style=background-color:lightgreen; type=submit value=Solve></input></form>').replace('DISPLAY:table-row','DISPLAY:none').replace(lastfis,lasttis).replace(lasteis,lastenow).replace(lasteis2,lastenow2).replace(lastsis,lastsnow).replace(lastsis2,lastsnow2).replace('absolute;','absolute;display:none;').replace(flatf,tlatf).replace(flongf,tlongf).replace(flatt,tlatt).replace(flongt,tlongt).replace(fbrg,tbrg).replace(fdist,tdist) + '</body>');
}
xzhr.open('post','//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php',true);
xzhr.send(xform);
} else {
document.getElementById('asms').href='mailto:' + em.trim() + '?subject=' + encodeURIComponent('Missing Two') + '&body=' + encodeURIComponent(document.URL.split('#')[0].split('?')[0] + suffbits); // + '?missingtwo=' + encodeURIComponent(encodeURIComponent(document.getElementById('dfix').innerHTML.replace('background: ','').replace('background:','').replace(');',')').replace(';',''))));
document.getElementById('asms').click();
}
}
}
โฆ in thechanged missing_twohtmlโs live
run link.
Previous relevant Earth Bearing Distance Missing Two Trip Tutorial is shown below.
If we were to nominate an โonions of the 4th dimensionโ improvement on top of the work of Earth Bearing Distance Missing Two Context Tutorial weโd nominate โฆ anyone, anyone โฆ yes, tenticle 5 of The Kraken โฆ weโd want to allow our โMissing Two Geographical places via Bearing and Distanceโ web application be turned into a trip planner by allowing for multiple legs, perhaps of a trip, to be โrepresentedโ by our new incarnation of the web application. As per usual, with extensions of functionality, here, it is optional, and manifested by โฆ anyone, anyone โฆ yes, tenticle 9 3/4 of The Kraken โฆ turning a hardcoded piece of (webpage) text into an HTML element with action logic behind it โฆ our TAHPOWTIAHEWALBI moment, you could say?!
Seriously though, it is rare that a sizeable trip happens as a one leg with the one bearing and distance component, so we turn our old web application into a โฆ
- recursive โฆ
- parent/child (webpage/iframe) relationship โฆ
- linked list (trip) legs
โฆ type of web application, in order to do that other thing we like to do, and that is to have the one (in this case just HTML/Javascript/CSS) codeset handle both simple and (optional) complex usage functionalities.
How do we differentiate a โtop.documentโ parent from an (HTML) iframe (element) child? We use โฆ
- address bar URL ? and & argument (?latf=[previousToLatitude]&longf=[previousToLongitude]) usage (and analysis) via โฆ checked for via โฆ
- <body onload=โmoremaybe();โ>
-
function moremaybe() {
var latto=location.search.split('latf=')[1] ? decodeURIComponent(location.search.split('latf=')[1].split('&')[0]) : '';
var longto=location.search.split('longf=')[1] ? decodeURIComponent(location.search.split('longf=')[1].split('&')[0]) : '';
if (latto != '' && longto != '') {
nextplease();
top.document.getElementById('goagain').style.display='block';
document.getElementById('latf').value=latto;
document.getElementById('latf').style.backgroundColor="pink";
cwhat[0]=false;
cwhat[1]=false;
if (!decided) {
if (!cwhat[5]) {
cwhat[5]=true;
}
if (!cwhat[4]) {
cwhat[4]=true;
}
decided=true;
}
top.document.getElementById("ltf").value=latto;
document.getElementById('longf').value=longto;
document.getElementById('longf').style.backgroundColor="pink";
cwhat[0]=false;
cwhat[1]=false;
if (!decided) {
if (!cwhat[5]) {
cwhat[5]=true;
}
if (!cwhat[4]) {
cwhat[4]=true;
}
decided=true;
}
top.document.getElementById("lgf").value=longto;
document.getElementById('dtop').style.display='none';
document.getElementById('trhead').style.display='none';
document.getElementById('trfoot').style.display='none';
document.getElementById('myt').border=0;
var recti=parent.document.getElementById('niframe').getBoundingClientRect();
parent.document.getElementById('niframe').height=eval(200 + eval(('' + recti.height).replace('px',''))) + 'px';
if (parent.document.getElementById('niframe') != top.document.getElementById('niframe')) {
var trecti=top.document.getElementById('niframe').getBoundingClientRect();
top.document.getElementById('niframe').height=eval(200 + eval(('' + trecti.height).replace('px',''))) + 'px';
}
setTimeout(checkfill, 500);
parent.document.getElementById("slong").innerHTML=":";
parent.document.getElementById("slong").title="";
parent.document.getElementById("slong").style.textDecoration="none";
//top.document.title+=' started ';
}
}
โฆ where you can see that โtop.documentโ (top) parent is just that โฆ top.document โฆ and that a parent of an (HTML) iframe (element) trip leg is referred to via โฆ parent.document โฆ and what is being done in the here and now of a simple scenario (just in the (top) parent) or a complex (non (top) parent leg) โฆ document โฆ references come into play. That parent.document.getElementById(โslongโ) refers to the dynamically changed method of adding legs, by turning the โฆ
- hardcoded โ:โ (text) of the To longitude textbox labelling โฆ into a clickable and onclick event working โฆ
-
document.getElementById('slong').style.cursor='pointer';
document.getElementById('slong').style.textDecoration='underline';
document.getElementById('slong').title='Click for another leg of a trip, perhaps?';
document.getElementById('slong').innerHTML='+';
โฆ optionally used, and dynamic extension to functionality โฆ our โonions of the 4th dimensionโ moment โฆ who said we donโt care about your health here?!
โฆ so that top.document.getElementById(โniframeโ) is the representation of that โtop.documentโ parentโs first (HTML) iframe (element) child.
Why ask that previous question? To have the one codebase service all the scenarios, we need (the code) to know โwhere it is atโ, so to speak.
Thechanged missing_twohtmlโs live
run link can have you planning your own โwhere of lifeโ trip itinerary of interest yourself.
Previous relevant Earth Bearing Distance Missing Two Context Tutorial is shown below.
Mapping and navigational apps wouldnโt be as popular as they are without โฆ
- satellite based geodata available to our mobile and laptop (and cars etcetera) devices and their software โฆ and โฆ
- the human urge to want to know where they are
โฆ and so to leave yesterdayโs Earth Bearing Distance Missing Two Primer Tutorial โproof of conceptโ web application the way it was, not showing much context to the latitude and longitude form โasksโ would be a missed opportunity.
In this sense, weโve decided to interface this web application to โฆ
- ourchanged tz_places
phpโs talents (last talked about with Other Side of the World Google Chart Tutorial) with PHP TimeZone places and deriving the nearest ones given a latitude and longitude geographical input
- and to our interface to the Google Chart Geo Chart showing places on the Earth relative to a world map
โฆ to give thechanged missing_twohtmlโs live
run link that optional map (or visual) extra context. This is accessible off links applied to the previously hardcoded โFromโ and โToโ table headers. Please feel free to give it a go to see what we mean.
Previous relevant Earth Bearing Distance Missing Two Primer Tutorial is shown below.
Get in a conversation with a Land Surveyor, and drop in your sentence, close to each other, the words โbearingโ and โdistanceโ and in all likelihood youโll get a smile. Is it a curved smile? Maybe, they are interested in the geodesic aspects to these two terms. You see, the rules of Euclidean geometry are all fine and good and used by Land Surveyors for small distances involving local mapping or small area mapping, where the curvature of the Earth is not really a factor. In fact, in the early days of Land Surveying, the plotting of an area might have been done using a table resting on a tripod, which hopefully made that table level (all good terrestrial surveying wants you to be perpendicular to the imaginary plumb bob hanging from your instrument, and hanging down in accordance with gravityโs laws). Geodesic interest for Land Surveyors tries to take into account the curvature of the Earth, which weโll assume for today, is a sphere, though in reality it takes on a spheroidal shape that is not quite a sphere.
Polar co-ordinate designations are an alternative โviewโ to placing yourself, as distinct from grid co-ordinates, or geographical latitude and longitude.
We talked about some of what we have written a proof of concept web application for today with the PHP Google Map Chart Bearing Distance Tutorial some time back, and revisited its excellent โฆ
very useful link that talks about the Haversine distance formula, as well
โฆ and rereading this excellent webpage, realized that two sets of formulae there (plus the great circle distance calculations before) could help us piece together a useful navigational web application that, out of โฆ
From Latitude, Longitude | Bearing, Distance | To Latitude, Longitude |
---|
โฆ we could get the user to fill out 2 of 3 columns of information above, and calculate the missing one for them.
How is this useful? Well, sometimes you want to know โฆ
- We are at X. We are crow flying to Y. In which direction do we set out? How far is it?
- We are at X. That looks like a nice direction to head, so what compass reading is that? If I go however far, where do I end up?
Second one for those dreamers and adventurers (or perhaps, orienteerers) methinks. Anyway, feel free to try the HTML and Javascript โs liverun link, or down below โฆ
Previous relevant PHP Google Map Chart Bearing Distance Tutorial is shown below.
There have been three recent things going on, for us, involving software integration of our interface to the great Google Chart Map Chart โฆ
- the work of PHP Wikipedia Australian List Integration Tutorial adding select (ie. Google Charts โonclickโ) event Nearest TimeZone=Z and YouTube=Y functionalities โฆ and also โฆ
- ongoing changes readying web applications that can work in an iOS WKWebView we started talking about at Conditional Alternative to Javascript Popup Windows in iOS Tutorial and which we shall return to โฆ and then todayโs new functionality to โฆ
- add new select (ie. Google Charts โonclickโ) event functionality to show a Bearing (degrees) and Distance (kilometres) and To table of information relative to a clicked From place
As a worker with a background in Land Surveying, of course, the words โbearingโ and โdistanceโ were part of the โbread and butterโ of this job. The modern day equipment can, at the observerโs tripod, and given the chainpersonโs placement of equipment, deal with both of these โmeasuresโ at once, but you can still use the old theodolites and distance measuring chains if you like. You take your measurements and use calculations like those underlying the workings of the web application of HTML and Javascript and CSS Survey Traverse Tutorial which are all fine and dandy if the distances are relatively small, because we can think โplanar geometryโ as we mostly learn at school. But if the measurements involve long enough distances, you need to take into account that Earth is, basically, round โฆ meanwhile, on the phone โฆ.
You donโt say. You donโt say. You donโt say.
โฆ
โWhatโd they say?โ โฆ
They didnโt say.
When distances are this large we need to turn towards โgeodesic calculationsโ and today โฆ
- with our calculation of โbearingsโ between two sets of latitude and longitude we turned to this very useful link that talks about the Haversine distance formula, as well, thanks โฆ and to help make the table of information more approachable we called on โฆ
- half hour time of day clock emojis we used for TimeZone Country Places Emoji Tutorial โฆ and โฆ
- used the cursor techniques we talked about at HTML/Javascript Guided Snake Game Primer Tutorial
Here are some โlive runsโ โฆ
- make your own Google Chart Map Chart
- left hand side of tutorial picture here
-
By The Time I Get To โฆ can be seen below โฆ
โฆ and hereโs the changed PHP mapphp changed in thisway.
Previous relevant PHP Wikipedia Australian List Integration Tutorial is shown below.
Yesterdayโs PHP Wikipedia Australian List Makeover Tutorial got us thinking more about โwhere of lifeโ functionality integration possibilities.
For us, with many โwhere of lifeโ web applications, the Google Charts Map Chart is a core part of the functionality, as the receptacle, and more and more often as time goes on, also a launching pad out to other concepts, such as โฆ
- TimeZone โฆ and โฆ
- Weather
โฆ two of the concepts hovering about our โOther Side of the Worldโ web application we last talked about with Other Side of the World Google Chart Tutorial, whose supervisory HTML other_side_of_the_worldhtmโs live
run, changed in thisway to tweak the the linking of โฆ
- latitude and longitude and (anywhere) placename โฆ to โฆ
- TimeZone place(s) โฆ and then (with great help from Weather Underground (thanks)) onto โฆ
- direct or nearby weather predictions
โฆ coming off a new Map Chart Google Chart and its select event menu option โฆ
- Nearest TimeZone=Z (and onto Other Side of the World and Weather)
- YouTube=Y (looking for placename)
โฆ the latter integrating us with YouTube API for Iframe embedded videos interface HTML/Javascript โparentโ web application called karaoke_youtube_api.htm HTML iframe elements in another direction additional to yesterdayโs usage. Along the way, we tweak the Google Map=G menu option, adding more map type options and zooming in a little less by default, and with the Nearby Airports=A option making the default be a search for 3 (rather than 4) nearby airports. A lot of this all happens because of the changes to โฆ
- map
phpโs Google Charts Map Chart interfaceโs live
run (changed thisway)
- Australian
Lighthouses australian_lighthouses
php (changed thisway)
- Australian
Waterfalls australian_waterfalls
php (changed thisway)
- Australian
Dams australian_dams
php (changed thisway)
- Australian
Ports australian_ports
php (changed thisway)
- Australian
National Parks australian_parks
php (changed thisway)
โฆ which all got changed to allow for an โAnimateโ feature, allowing for an automated right to left โanimationโ (via hashtagging) of the Wikipedia based slides near the top of this suite of web applicationโs webpages. We hope you get to try all this out for yourself.
Previous relevant PHP Wikipedia Australian List Makeover Tutorial is shown below.
Some time back we linked a Wikipedia โlistโ webpage to the Google Charts Map Chart functionality with PHP Modularization for Lighthouses in Australia Tutorial.
Weโre revisiting, and finding some โpeerโ web applications, linked by a dropdown, that all โฆ
- access a relevant Wikipedia โlistโ webpage for Australian โthingsโ and mentioning latitude and longitude โฆ which link to โฆ
- Google Charts Map Chart
โฆ for all of โฆ
We were inspired to take on this โmakeoverโ of โwhere of lifeโ functionalities because earlier on today we discovered a stupendous online resource for Australian geography enthusiasts, the Bonzle Digital Atlas of Australia, with incredibly detailed and flexible search mechanisms, thanks heaps!
Weโve decided to include extra buttons (to those already linking to Google Maps links and to the relevant Wikipedia webpage) for that suite of web applications above for โฆ
- Bonzle Digital Atlas of Australia
- Australian government website (sometimes)
- YouTube API for Iframe embedded videos interface HTML/Javascript โparentโ web application called karaoke_youtube_api.htm HTML iframe elements
Great for research and โsurfing the Australian worldโ! Lose yourself!
What happened Javascript (australian_lighthousesjs changed thisway) and PHP wise?
- australian_lighthouses
php (changed thisway)
- australian-waterfalls
php
- australian_dams
php
- australian_ports
php
- australian_parks
php
Previous relevant PHP Modularization for Lighthouses in Australia Tutorial is shown below.
Today we want to try two more things โฆ
- continuing on with our PHP code (you could call australian_lighthouses
php) for our Australian Lighthouses project
- talk about PHP glob and its modularization sensibilities
โฆ so letโs talk about the second one first โฆ itโs south of north โฆ chortle, chortle.
What does PHPโs glob do? It is doing functionality like the โunderworkingsโ of any browse button you would see would do when you have a hard disk (in your life) โฆ unfortunately, this is no longer a given (with mobile technology and the โcloudโ challenging this thinking, sometimes). Give glob a file specification and a directory to start with, and it will happily (if you were both โglobularโ and โmodularโ you would be, too) provide you with a list of filenames, so that we use it to construct this PHP function for use with our lighthouses web application โฆ
function selcreate($def) {
$ret=$def;
$selstr='<select onchange=" window.location=this.value; "><option value="' . str_replace(" ", "_", strtolower($def)) . '_lighthouses.php">' . $def . '</option>';
$cnt=0;
foreach (glob("*_lighthouses.php") as $filename) {
if (strpos(($filename . "*"), (str_replace(" ", "_", strtolower($def)) . '_lighthouses.php*')) === false) {
$cnt++;
$newidea=str_replace("_", " ", str_replace("_lighthouses.php", "", strtolower($filename)));
$newideas=explode(" ", $newidea);
$ideas=strtoupper(substr($newideas[0],0,1)) . strtolower(substr($newideas[0],1));
for ($ii=1; $ii<sizeof($newideas); $ii++) {
$ideas.=(" " . strtoupper(substr($newideas[$ii],0,1)) . strtolower(substr($newideas[$ii],1)));
}
$selstr.='<option value="' . $filename . '">' . $ideas . '</option>';
}
}
if ($cnt > 0) return $selstr . "</select>";
return $ret;
}
โฆ and hope you can see that glob could be used for PHP code to self-detect sibling variation programs, so that, for instance, if we โplonkedโ (ie. eg. (s)ftp it) an egypt_lighthouses.php (probably with an egypt_lighthouses.js accompanying Javascript file) into the same directory as our โฆ
- australian_lighthouses
php (changed from yesterday as per thislink) (uses australian_lighthouses
js) to arrive at a live
run
- new_zealand_lighthouses
php (uses new_zealand_lighthouses
js) to arrive at a live
run
- ireland_lighthouses
php (uses ireland_lighthouses
js) to arrive at a live
run
โฆ it would automatically be added into the functionality of its siblings without you having to change any code of those siblings โฆ and that egypt_lighthouses.php is free to be a web application with a totally different method of functionality โฆ cute, huh?!
As a matter of fact ireland_lighthouses.php is quite different, and if you examine the code, you will see that the Javascript putElement(s)By via PHP Relative URLs Tutorial is more apt to a discussion of its workings.
You see, there are so many many different ways to โskin a catโ in Information Technology, quite often โฆ not always โฆ but โquite oftenโ โฆ and why be cornered into thinking there is only one way to do things?
The other thing youโll find is that even though ireland_lighthouses.php differs a lot to its nearest matching sibling (in terms of methodology), new_zealand_lighthouses.php the Javascript corresponding codesets called ireland_lighthouses.js and new_zealand_lighthouses.js are only superficially different โฆ in other words our PHP coalesces concepts into a similar โclientโ look โฆ a โmodularizationโ of sorts โฆ not everybodyโs sort, but a sort none the less โฆ and this begs a question?
Why is โmodularizationโ a good thing? Well, to me, you donโt have to have any โmodularizationโ going on at all, and this is fine by me, but you must deal with issues that allow you to modify many many codesets efficiently and accurately in vastly different ways to be efficient, or be โmodularโ and be able to, perhaps, even, automate your changes, because of these โmodularโ patterns youโve created โฆ many people find โmodularizationโ blissful โฆ and often it suits the work patterns for teams of programmers. Perhaps you want to read about MVC (and its like) as a coding modularization idea for PHP (or many other programming languages, for that matter).
Previous releveant PHP/Javascript Asynchronous Lighthouses in Australia Tutorial is shown below.
Today we want to try two things โฆ
- continuing on with our PHP code (you could call australian_lighthouses
php) for our Australian Lighthouses project
- talk about Javascript asynchronous script tag option
โฆ so letโs talk about the second one first โฆ itโs south โฆ chortle, chortle.
Why should you be interested in the HTMLโs script tag attributes โฆ
- asynch=โasynchโ
- defer=โdeferโ
? Well, we want our web pages to load as fast as possible. Yaaaaaa?! So if there was the mechanism to do more than one bit of ((client) Javascript) thinking at a time would you avail yourself of the opportunity โฆ or would you pick whatโs behind door 3?
Do you want to hear more on this theory wise? It seems to me, there are web application mission critical parts, and there are embellishments, quite often โฆ โnice to havesโ but not โmission criticalโ โฆ well, if those โnice to havesโ could be arranged not to hog all the web application designated CPU that would be good, wouldnโt it?! Yaaaaaaaaaaa?!
So, that, in theory, is y why.
Now back to the project at hand โฆ Australian Lighthouses โฆ donโt you think some geographical sorting options and place name sorting options might be useful? Yaaaaaaaaaaaaaaaaa?! But for us it doesnโt feel mission critical โฆ so we โฆ
- place the logic in some external Javascript called australian_lighthouses
js
- we load it from the PHP via
<script type=โtext/javascriptโ src=โaustralian_lighthouses.jsโ async=โasyncโ></script>
โฆ and this amounts to the only change to todayโs PHP code from yesterday as per thislink
โฆ and this becomes a way to modularize your thinking regarding a project โฆ please donโt think there are not a myriad of other ways โฆ this is just one idea here.
With regard to how we approached our external Javascript we did not demand anything (much) of our parent PHP and this may not be the fastest way to approach this. What we mean by that is that, perhaps, as a general rule, external Javascript can perform faster with the parent PHP or HTML leaving it with a lot more HTML element id=โ[elementId]โ to hang its hats on, so to speak โฆ instead, here, we acted innocently with our Javascript and used lots of calls to the Javascript DOM method getElementsByTagName() (which results in an array return value). Perhaps calls to getElementById() via (parent) arranged id=โ[elementId]โ would be faster?! Today, as with the previous Static HTML Javascript Primer Tutorial we concentrated on the โmodularโ feel to additional external Javascript code ideas.
So try a liverun to see what we mean.
Previous relevant PHP Lighthouses in Australia Primer Tutorial is shown below.
Today we examine some of the methodology behind a project idea.
Projects need โฆ
- an idea โฆ ours came from listening to the radio and hearing about Lighthouses, and how the technologies had changed what they look like and how they function these days โฆ to quote Wikipedia with respect to Australian Lighthouses (thanks) โฆ
The first lighthouse was Macquarie Lighthouse, which was lit in 1793 as a tripod mounted wood and coal fired beacon. The last manned lighthouse was Maatsuyker Island Lighthouse, off the south coast of Tasmania, which was automated in 1996.
- a means to access information โฆ much easier these days with the search engines โฆ we went with a Google Search as per list of lighthouse positions โฆ which led to โฆ
- the information source(s) โฆ we settled, and were not surprised about the source, for Wikipediaโs List of lighthouses and lightvessels in Australia โ Wikipedia โฆ then, once happy about the quality of the source information, analyzed โฆ
- the source data format โฆ initially, at least, via View->Page Source, relative to the webpage โฆ to get ideas for how to parse the data โฆ so that we can determine a โฆ
- programming language of choice โฆ which is PHP โฆ no surprise here โฆ will need a server-side language โฆ and a method like PHPโs file_get_contents() โฆ from there โฆ
- PHP coding to parse the data and put it into another format that value adds โฆ otherwise why do it, as the Wikipedia information is fine as is โฆ that is where we determine that we should โฆ
- include an iframe that uses the Google Chart Map Chart to add that extra overall positional view of Lighthouses โฆ a definite asset to the readerโs understanding of the subject โฆ definitely a โwhereโ web application โฆ and in doing this we notice that โฆ
- Google Chart Map Chart map
php web application needed to be able to handle much larger input data streams than it could in its previous incarnation of only allowing PHP $_GET[] parameters โฆ so we change it to allow $_POST[] parameters โฆ maybe you noticed this with yesterdayโs PHP/Javascript/HTML Google Chart Map Onclick Tutorial as shown below โฆ as this meant that โฆ
- we need an HTML form that POSTs to the iframe with the Google Chart Map Chart map.php web application allowable because we are on the same domain with this thinking โฆ and using an HTML textarea element to store the huge string of Lighthouse data that will be passed across via urldecode($_POST[โdataโ]) at map.php โฆ using PHPโs urldecode() and urlencode() methods and Javascriptโs decodeURIComponent() method โฆ as well as utilizing โฆ
- Google Chart Map Chart map.php web application onclick and tooltip functionality weโve been working on lately โฆ hence the talk about this below โฆ working out what (component) tools could do with a โmakeoverโ is an extremely important part of any project and can be a useful compartmentalizing of the project
โฆ and so we end up with our liverun behind which is the PHP programming source code you could call australian_lighthouses
php for your perusal.
Previous relevant PHP/Javascript/HTML Google Chart Map Onclick Tutorial is shown below.
They say โthe knee boneโs connected to the thigh boneโ then they say โthe thigh boneโs connected to the โฆ hip boneโ then they say โletโs call the whole thing offโ โฆ sometimes.
Today we say โthe onmouseover event is connected to the onclick eventโ then we say โthe onclick event is connected to the online woooooorldโ โฆ โdo โฆ the hokey pokeyโ x3 โฆ โthatโs what the onclick event preceeded by the onmouseover event within the environs you are encountering โฆ is all aboutโ.
That news is pretty good actually, because it means mobile users are not missing out on much not having easy access to any onmouseover (ie. hover) functionality โฆ theyโll still reach any onclick logic you present them, in the default case of events where onclick is a valid โtouchโ event as well.
So the data structure of arrangements to allow for this onclick functionality is intrinsically the same as allowed for yesterday with the PHP/Javascript/HTML Google Chart Map Tooltips Tutorial as shown below, but we just check for some more delimitation issue matters, and our updated prompting window logic gets quite โblurbyโ as per the Javascript (via PHP) โฆ
echo " datalinesuffix = prompt('Enter decimal Latitude,Longitude ' + thisline + extra + ' (for no more hit Cancel button and append with ' + '\\n\\n' + ',\"A tooltip and clicking link for Google Map of <a target=_blank href=https://www.google.com.au/maps/place/' + encodeURIComponent(dlp2) + '>' + dlp2 + '</a>\" ' + '\\n\\n' + ' or maybe perhaps ' + '\\n\\n' + ',\"A tooltip and clicking link for Google Map based on latitude and longitude of <a target=_blank href=https://maps.google.com.au/maps?' + encodeURIComponent('z=15&t=m&q=loc:') + '{latitude}{longitude}>' + dlp2 + '</a>\"' + '\\n\\n' + ' optionally (as (just) two examples of what is possible with HTML included (activates with onclick bit not onmouseover))', thisdef); " . "\n";
echo ' if (datalinesuffix != null) { if (datalinesuffix.indexOf("{latitude}") != -1) { dlsa=datalinesuffix.split(","); if (dlsa[0].indexOf("-") == -1) { datalinesuffix=datalinesuffix.replace("{latitude}",encodeURIComponent("+" + dlsa[0])); } else { datalinesuffix=datalinesuffix.replace("{latitude}",encodeURIComponent(dlsa[0])); } } if (datalinesuffix.indexOf("{longitude}") != -1) { dlsa=datalinesuffix.split(","); if (dlsa.length > 1) { if (dlsa[1].indexOf("-") == -1) { datalinesuffix=datalinesuffix.replace("{longitude}",encodeURIComponent("+" + dlsa[1])); } else { datalinesuffix=datalinesuffix.replace("{longitude}",encodeURIComponent(dlsa[1])); } } } } ' . "\n";
โฆ as again we are making use of $_GET[] parameters coming into the PHP at the server side.
The bigger picture plan for how this helps something else we are trying will become apparent over time โฆ in the fullness of time โฆ at the appropriate juncture of juxtapositions.
Letโs see some PHP code in liveaction for this tutorial where you define your map characteristics and data.
Link to Google Chart Tools โspiritual homeโ โฆ via Google.
Link to Google Chart Tools Map information โฆ via Google.
Link to Google Chart tooltips information โฆ via Google.
Link to some downloadable PHP programming code โฆ rename to mapphp which changed from yesterday as per thislink.
Previous relevant PHP/Javascript/HTML Google Chart Map Tooltips Tutorial is shown below.
Here is a tutorial that is revisiting Google Graphs API, or Google Chart Tools, and its Map functionality, which we first talked about with PHP/Javascript/HTML Google Chart Map Tutorial as shown below. Please read โฆ
Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.
Why are we revisiting? Well, we are interested in the interactive side to this wonderful product. We are going to start with a look into โtooltipsโ. Tooltips are those optional informational features of some webpages that happen when hovering over an HTML element, principally through the filling out of an HTML elementโs title global attribute.. Google Charts functionality amounts to the use of Javascript, and, these days, SVG HTML elements, so โtooltipsโ are very relevant to the โuser experienceโ when using Google Charts. With the Map Chart, the latitude, laongitude set is combined with a title, which can be the default โtooltipโ shown, as this is all fine for many usages, but we want to extend it so that that title doesnโt have to be the tooltip.
The integration of this added functionality into the Google Chart Map Chart involves adding an extra โstringโ column to the data table as per the bold bits of the new Javascript (via PHP) snippet โฆ
if (isset($_GET['value']) && (isset($_GET['tooltip']) || strpos($GETdata, "'") !== false)) {
echo " var data = new google.visualization.DataTable(); /" . "/" . $GETlabel . $GETvalue . " \n";
echo " data.addColumn('number', '" . str_replace("'","",str_replace(",","",str_replace("['","",$GETlabel))) . "'); \n";
echo " data.addColumn('number', " . str_replace(",", "); data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}}); data.addColumn('string', ", str_replace("]","",$GETvalue)) . "); \n";
echo " data.addRows([ \n";
echo str_replace("''" . "''", "''", str_replace("~", "'", substr($GETdata,1)));
echo " ]); \n";
} else {
echo ' var data = google.visualization.arrayToDataTable([ ' . "\n";
echo " " . $GETlabel . $GETvalue . " \n";
echo str_replace("''" . "''", "''", str_replace("~", "'", $GETdata));
echo " ]);\n";
}
โฆ making use of $_GET[] parameters coming into the PHP at the server side โฆ youโll find that Javascript loves to work with PHP as one of those Fred and Ginger relationships of the programming world โฆ youโll be happier writing Javascript from your PHP too โฆ try it and youโll see the advantages time and again and again and again โฆ did we leave out one? โฆ and again.
The bigger picture plan for how this helps something else we are trying will hopefully become apparent over time.
Letโs see some PHP code in liveaction for this tutorial where you define your map characteristics and data.
Link to Google Chart Tools โspiritual homeโ โฆ via Google.
Link to Google Chart Tools Map information โฆ via Google.
Link to Google Chart tooltips information โฆ via Google.
Link to some downloadable PHP programming code โฆ rename to mapphp which changed from the days of Google Charts Emailing Primer Tutorial as per thislink.
Previous relevant PHP/Javascript/HTML Google Chart Map Tutorial is shown below.
Here is a tutorial that introduces you to Google Graphs API, or Google Chart Tools, and its Map functionality.
Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.
Letโs see some PHP code in live action for this tutorial where you define your map characteristics and data.
Link to Google Chart Tools โspiritual homeโ โฆ via Google.
Link to Google Chart Tools Map information โฆ via Google.
Link to some downloadable PHP programming code โฆ rename to mapphp.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.