<!DOCTYPE html>
<html lang="en">
<head>
<title>cities.html</title>
<meta charset="utf-8">
<link rel="shortcut icon" href="ok.ico">

<style>
body{margin:0px;background-color:#025;overflow:hidden;}
td{text-align:center;padding:0px;color:#fff;font-family:Monospace;font-size:12pt;}
span{position:absolute;font-family:Arial;font-size:12pt;text-align:center;z-index:1;}
</style>

<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
	{
		"imports":{
			"three":"https://unpkg.com/three@0.156.0/build/three.module.js",
			"three/addons/":"https://unpkg.com/three@0.156.0/examples/jsm/"
		}
	}
</script>

</head>

<body>

<div id="dedo" style="position:absolute;left:10px;top:10px;padding:4px;background-color:#000;border:2px outset #cc6;display:none;">?</div>

<span id="aaa" style="position:absolute;left:80%;top:10px;color:#0cf;font-size:20.5px;">... loading ...</span>

<span id="idtextu" onclick="changetextu();" style="position:absolute;left:80%;top:40px;color:#fc0;font-style:normal;cursor:pointer;">click to change texture &check;</span>

<button style="position:absolute;left:84%;top:84%;background-color:transparent;text-align:center;"><a id="code" href="cities.txt" target="_blank" style="color:#fc0;text-decoration:none;font-size:16pt;">The Code</a></button>

<span id="spanC" style="left:10px;top:10px;color:#0cf;font-size:20.5pt;"></span>
<span id="inps" style=left:20px;top:40px;color:#fc0;width:300px;">input number ... <input id="inpi" type="text" value=? autocomplete="off" style="color:#f00;font-weight:bold;font-family:Courier;font-size:20.5px;text-align:center;width:60px;padding:0px;"></input><button style="width:26px;height:26px;padding:0px;border-radius:0px;font-weight:bold;">&check;</button></span>
<span id="paranu" style="white-space:nowrap;left:10px;width:250pt;top:100px;color:#fc0;font-family:Courier;font-size:10.25p7;text-align:left;font-style:normal;height:310px;overflow-y:auto;overflow-x:hidden;"></span>

<script type="module">

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import {  CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';

function FibonacciSphereUma(uma){
	x=0;y=0;z=0;varla=0;varlo=0;
	group.rotation.y=0;group.rotation.x=0;
	camera.position.set(0,0,5);
	if(ns[uma]=="N"){
		varla=(90-la[uma])*degrad;
	}else{
		varla=(180-(90-la[uma]))*degrad;
	}
	if(ew[uma]=="E"){
		varlo=(90-lo[uma])*degrad;
	}else{
		varlo=(90+lo[uma])*degrad;;
	}
	y=Math.cos(varla);
	const r=Math.sqrt(1-Math.pow(y,2));
	x=Math.cos(varlo)*r;z=Math.sin(varlo)*r;

	boly[uma]=boly[0].clone();
	cor=get_random_color();

	boly[uma].material=new THREE.MeshStandardMaterial({color:cor,emissive:cor,emissiveIntensity:0.1});
	boly[uma].position.set(x*1.5,y*1.5,z*1.5);
	coly[0].position.set(x*1.5,y*1.5,z*1.5);
	coly[1].position.set(x*1.5,y*1.5,z*1.5);
	coly[2].position.set(x*1.5,y*1.5,z*1.5);
	coly[3].position.set(x*1.5,y*1.5,z*1.5);

	boly[uma].scale.set(2,2,2);
	boly[uma].rotation.set(0.5,0,0);

	boly[uma].name=no[uma];
	boly[uma].valuela=la[uma];
	boly[uma].valuens=ns[uma];
	boly[uma].valuelo=lo[uma];
	boly[uma].valueew=ew[uma];

	alvos.push(boly[uma]);
	group.add(boly[uma]);
	group.rotation.y=-Math.PI/2+varlo;group.rotation.x=Math.PI/2-varla;
	w=0;
}

var renderer,scene,camera,geometry,material,controls,amb,textureLoader,textu,Earthgeo,Earthmat;
var altera=0;
var textuval=1;
var group=new THREE.Group();
var cor,color;
var sub;

var cit=[];var lato=[];var long=[];var nom=[];var la=[];var lo=[];var no=[];var ns=[];var ew=[];

var k=0;
var w=0;
var ww=0;
var apa=1;
var Earth;
var numPoints=0;
var degrad=0.0174532925;

var boly=[];var coly=[];var geo=[];var mat=[];var moly=[];
var bolygeo,bolymat,colygeo,colymat;

var mouse=new THREE.Vector2();
var raycaster=new THREE.Raycaster();
var psect=[];
var alvos=[];
var isected,isects;

var bId=function(id){return document.getElementById(id);}
var dspanC=bId("spanC");
var didtextu=bId("idtextu");
var daaa=bId("aaa");
var dparanu=bId("paranu");
var dinpi=bId("inpi");
var ddedo=bId("dedo");

var x=0;var y=0;var z=0;var varla=0;var varlo=0;

var ds="";
var nu=0;
var onde="";

function init(){

	didtextu.onclick=function XIDTEXTU(){textucha();}
	daaa.innerText="Cities of the Earth";
	dinpi.onchange=function XDINPI(){
		if(dinpi.value<numPoints && dinpi.value>0){
			FibonacciSphereUma(dinpi.value);//dspanC.innerText=no[dinpi.value];
		}}

	renderer=new THREE.WebGLRenderer({antialias:true,alpha:true});
	renderer.setPixelRatio(window.devicePixelRatio);
	renderer.setSize(window.innerWidth,window.innerHeight);
	renderer.setClearColor('#069',1);
	renderer.outputColorSpace=THREE.LinearSRGBColorSpace;

	document.body.appendChild(renderer.domElement);

	scene=new THREE.Scene();

	camera=new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,1000);
	camera.position.set(0,0,5);
	
	amb=new THREE.AmbientLight("#fff",3);
	scene.add(amb);

	controls=new OrbitControls(camera, renderer.domElement);
	//controls.maxAzimuthAngle = Math.PI /2;  
	//controls.minAzimuthAngle = -Math.PI / 2;
	//controls.maxPolarAngle = Math.PI/1;
	//controls.minPolarAngle = 0;

//	document.addEventListener('mousedown',onMouse);
	document.addEventListener('mousemove',onMouse);
	window.addEventListener('resize',onResize,false);

	// Earth
	textureLoader=new THREE.TextureLoader();
	textu=new THREE.TextureLoader().load("img/Equirectangular_projection_SW_3.jpg");
	Earthmat=new THREE.MeshStandardMaterial({color:"#fff",map:textu,transparent:true,opacity:1});

	Earthgeo=new THREE.SphereGeometry(1.5,32,32);
	Earth=new THREE.Mesh(Earthgeo,Earthmat);
	Earth.rotation.set(0,-1.57,0);

	geo[1]=new THREE.SphereGeometry(0.01,32,32);
	mat[1]=new THREE.MeshStandardMaterial({color:'#09f'});
	moly[1]=new THREE.Mesh(geo[1],mat[1]);
	moly[1].geometry.translate(0,0,0.1);

	geo[2]=new THREE.SphereGeometry(0.01,32,32);
	mat[2]=new THREE.MeshStandardMaterial({color:'#0f0'});
	moly[2]=new THREE.Mesh(geo[2],mat[2]);
	moly[2].geometry.translate(0,0.1,0);

	geo[3]=new THREE.SphereGeometry(0.01,32,32);
	mat[3]=new THREE.MeshStandardMaterial({color:'#f00'});
	moly[3]=new THREE.Mesh(geo[3],mat[3]);
	moly[3].geometry.translate(0.1,0,0);

	coly[0]=new THREE.AxesHelper(0.1);

	coly[0].add(moly[1]);

	coly[0].add(moly[2]);

	coly[0].add(moly[3]);

	coly[1]=coly[0].clone();
	coly[1].rotation.set(Math.PI/3,0,0);

	coly[2]=coly[0].clone();
	coly[2].rotation.set(0,Math.PI/3,0);

	coly[3]=coly[0].clone();
	coly[3].rotation.set(0,0,Math.PI/3);

	group.add(coly[0]);
	group.add(coly[1]);
	group.add(coly[2]);
	group.add(coly[3]);

	bolygeo=new THREE.SphereGeometry(0.02,32,32);
	bolymat=new THREE.MeshStandardMaterial({color:'#000'});
	boly[0]=new THREE.Mesh(bolygeo,bolymat);

	dados();

	render();

	// init end
}

function get_random_color(){
	color="";
	for(let i=0;i<3;i++){
        	sub=Math.floor(Math.random()*(256-64)+64).toString(16);
	       	color +=(sub.length==1?"0"+sub:sub);
    	}
	//daaa.innerText=color;
    	return "#"+color;
}

function onMouse(event){
ddedo.style.top=-20+event.clientY+"px";
ddedo.style.left=30+event.clientX+"px";
	mouse.x=(event.clientX/window.innerWidth)*2-1;
	mouse.y=-(event.clientY/window.innerHeight)*2+1;
	mouse.z=0;
	raycaster.setFromCamera(mouse,camera);
	isects=raycaster.intersectObjects(alvos,false);
	if(isects.length>0){
		if(isected!=isects[0].object){
			isected=isects[0].object;//dspanC.innerText=isected.name;
			ddedo.style.display="";
			//ddedo.innerText=isected.name + "\n lat: " +isected.valuela + " " + isected.valuens + "\n lon: " +isected.valuelo + " " + isected.valueew;
			ddedo.innerHTML="<table><tr><td colspan='3'>" + isected.name + "</td></tr><tr><td style='text-align:left;'>latitude:</td><td style='text-align:right;'>" + Number(isected.valuela).toFixed(2) + " " + isected.valuens + "</td></tr><tr><td style='text-align:left;'>longitude:</td><td style='text-align:right;'>" + Number(isected.valuelo).toFixed(2) + " " + isected.valueew + "</td></tr></table>";

 		}
	}else{
		isected=null;dspanC.innerText="";
		ddedo.style.display="none";
	}
}

function textucha(){
	textuval=1-textuval;
	if(textuval==0){
		textu=new THREE.TextureLoader().load("img/earth_800.jpg");amb.intensity=5;
	}else{
		textu=new THREE.TextureLoader().load("img/Equirectangular_projection_SW_3.jpg");amb.intensity=3;
	}
	Earth.material=new THREE.MeshStandardMaterial({color:"#fff",map:textu,transparent:true,opacity:1});
}

function onResize(){
	camera.aspect=window.innerWidth/window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize(window.innerWidth,window.innerHeight);
}

function animate(){
	requestAnimationFrame(animate);
	controls.update();
	if(renderer){render();}
}

function render(){
	if(altera==0){alterando();}
	if(altera==1){
		group.rotation.y  +=0.001;

		w +=0.01;if(w>2){w=0;}

		for(let j=1;j<numPoints;j++){if(boly[j]){boly[j].scale.set(w,w,w);}}


		if(coly[0] && coly[1] && coly[2] && coly[3]){
			coly[0].rotation.x +=0.1;coly[0].rotation.y +=0.1;coly[0].rotation.z +=0.1;
			coly[1].rotation.x -=0.1;coly[1].rotation.y -=0.1;coly[1].rotation.z -=0.1;
			coly[2].rotation.x +=0.1;coly[2].rotation.y +=0.1;coly[2].rotation.z +=0.1;
			coly[3].rotation.x -=0.1;coly[3].rotation.y -=0.1;coly[3].rotation.z -=0.1;
		}

		renderer.render(scene,camera);
	}	
}

function alterando(){
	var myTimeout=setTimeout(segue,300);
	function segue(){
		for(let j=1;j<numPoints;j++){if(boly[j]){group.add(boly[j]);group.add(coly[j]);}}
		group.add(Earth);
		scene.add(group);
	}
	altera++;
	animate();
}

function dados(){

var h=0;

h++;cit[h]="Aberdeen, Scotland____________*5715*N*  215*W";
h++;cit[h]="Adelaide, Australia___________*3492*S*13860*E";
h++;cit[h]="Algiers, Algeria______________*3683*N*  300*E";
h++;cit[h]="Amsterdam, Netherlands________*5237*N*  488*E";
h++;cit[h]="Ankara, Turkey________________*3992*N* 3292*E";
h++;cit[h]="Asunci\xF3n, Paraguay____________*2525*S* 5767*W";
h++;cit[h]="Atibaia,S\xE3o Paulo, Brazil_____*2309*S* 4657*W";
h++;cit[h]="Athens, Greece________________*3797*N* 2372*E";
h++;cit[h]="Auckland, New Zealand_________*3687*S*17475*E";
h++;cit[h]="Bangkok, Thailand_____________*1375*N*10050*E";
h++;cit[h]="Barcelona, Spain______________*4138*N*  215*E";
h++;cit[h]="Beijing, China________________*3992*N*11642*E";
h++;cit[h]="Bel\xE9m, Brazil_________________* 147*S* 4848*W";
h++;cit[h]="Belfast, Northern Ireland_____*5462*N*  593*W";
h++;cit[h]="Belgrade, Serbia______________*4487*N* 2053*E";
h++;cit[h]="Berlin, Germany_______________*5250*N* 1342*E";
h++;cit[h]="Birmingham, England___________*5242*N*  192*W";
h++;cit[h]="Bogot\xE1, Colombia______________* 453*N* 7425*W";
h++;cit[h]="Bombay, India_________________*1900*N* 7280*E";
h++;cit[h]="Bordeaux, France______________*4483*N*   52*W";
h++;cit[h]="Bras\xEDlia, Brazil______________*1579*S* 4788*W";
h++;cit[h]="Bremen, Germany_______________*5308*N*  882*E";
h++;cit[h]="Brighton, UK__________________*5082*N*   15*W";
h++;cit[h]="Brisbane, Australia___________*2748*S*15313*E";
h++;cit[h]="Bristol, England______________*5147*N*  258*W";
h++;cit[h]="Brussels, Belgium_____________*5087*N*  437*E";
h++;cit[h]="Bucharest, Romania____________*4442*N* 2612*E";
h++;cit[h]="Budapest, Hungary_____________*4750*N* 1908*E";
h++;cit[h]="Buenos Aires, Argentina_______*3458*S* 5837*W";
h++;cit[h]="Cairo, Egypt__________________*3003*N* 3135*E";
h++;cit[h]="Calcutta, India_______________*2257*N* 8840*E";
h++;cit[h]="Cambridge, UK_________________*5221*N*  119*E";
h++;cit[h]="Canton, China_________________*2312*N*11325*E";
h++;cit[h]="Cape Town, South Africa_______*3392*S* 1837*E";
h++;cit[h]="Caracas, Venezuela____________*1047*N* 6703*W";
h++;cit[h]="Cayenne, French Guiana________* 482*N* 5230*W";
h++;cit[h]="Chihuahua, Mexico_____________*2862*N*10608*W";
h++;cit[h]="Chongqing, China______________*2977*N*10657*E";
h++;cit[h]="Copenhagen, Denmark___________*5567*N* 1257*E";
h++;cit[h]="C\xF3rdoba, Argentina____________*3147*S* 6417*W";
h++;cit[h]="Dakar, Senegal________________*1467*N* 1747*W";
h++;cit[h]="Darwin, Australia_____________*1247*S*13085*E";
h++;cit[h]="Djibouti, Djibouti____________*1150*N* 4305*E";
h++;cit[h]="Dublin, Ireland_______________*5333*N*  625*W";
h++;cit[h]="Durban, South Africa__________*2988*S* 3088*E";
h++;cit[h]="Edinburgh, Scotland___________*5592*N*  317*W";
h++;cit[h]="Frankfurt, Germany____________*5012*N*  868*E";
h++;cit[h]="Georgetown, Guyana____________* 675*N* 5825*W";
h++;cit[h]="Glasgow, Scotland_____________*5583*N*  425*W";
h++;cit[h]="Greenwich, England____________*5148*N*    2*W";
h++;cit[h]="Guatemala City, Guatemala_____*1462*N* 9052*W";
h++;cit[h]="Guayaquil, Ecuador____________* 217*S* 7993*W";
h++;cit[h]="Hamburg, Germany______________*5355*N* 1003*E";
h++;cit[h]="Hammerfest, Norway____________*7063*N* 2363*E";
h++;cit[h]="Havana, Cuba__________________*2313*N* 8238*W";
h++;cit[h]="Helsinki, Finland_____________*6017*N* 2500*E";
h++;cit[h]="Hobart, Tasmania______________*4287*S*14732*E";
h++;cit[h]="Hong Kong, China______________*2233*N*11418*E";
h++;cit[h]="Iquique, Chile________________*2017*S* 7012*W";
h++;cit[h]="Irkutsk, Russia_______________*5250*N*10433*E";
h++;cit[h]="Jakarta, Indonesia____________* 627*S*10680*E";
h++;cit[h]="Jerusalem, Israel_____________*3177*N* 3521*E";
h++;cit[h]="Johannesburg, South Africa____*2620*S* 2807*E";
h++;cit[h]="Kingston, Jamaica_____________*1798*N* 7682*W";
h++;cit[h]="Kinshasa, Congo_______________* 430*S* 1528*E";
h++;cit[h]="Kuala Lumpur, Malaysia________* 313*N*10170*E";
h++;cit[h]="La Paz, Bol\xEDvia_______________*1645*S* 6837*W";
h++;cit[h]="Leeds, England________________*5375*N*  150*W";
h++;cit[h]="Lima, Peru____________________*1200*S* 7703*W";
h++;cit[h]="Linz, Austria_________________*4831*N* 1429*E";
h++;cit[h]="Lisbon, Portugal______________*3873*N*  915*W";
h++;cit[h]="Liverpool, England____________*5342*N*  300*W";
h++;cit[h]="London, England_______________*5153*N*    8*W";
h++;cit[h]="Lyons, France_________________*4575*N*  483*E";
h++;cit[h]="Madrid, Spain_________________*4043*N*  370*W";
h++;cit[h]="Manchester, England___________*5350*N*  225*W";
h++;cit[h]="Manila, Philippines___________*1458*N*12095*E";
h++;cit[h]="Marseilles, France____________*4333*N*  533*E";
h++;cit[h]="Mazatl\xE1n, Mexico______________*2320*N*10642*W";
h++;cit[h]="Mecca, Saudi Arabia___________*2148*N* 3975*E";
h++;cit[h]="Melbourne, Australia__________*3778*S*14497*E";
h++;cit[h]="Mexico City, Mexico___________*1943*N* 9912*W";
h++;cit[h]="Milan, Italy__________________*4545*N*  917*E";
h++;cit[h]="Monte Verde, Minas Gerais_____*2284*S* 4628*W";
h++;cit[h]="Montevideo, Uruguay___________*3488*S* 5617*W";
h++;cit[h]="Moscow, Russia________________*5575*N* 3760*E";
h++;cit[h]="Munich, Germany_______________*4813*N* 1158*E";
h++;cit[h]="Nagasaki, Japan_______________*3280*N*12995*E";
h++;cit[h]="Nagoya, Japan_________________*3512*N*13693*E";
h++;cit[h]="Nairobi, Kenya________________* 142*S* 3692*E";
h++;cit[h]="Nanjing (Nanking), China______*3205*N*11888*E";
h++;cit[h]="Naples, Italy_________________*4083*N* 1425*E";
h++;cit[h]="New Delhi, India______________*2858*N* 7720*E";
h++;cit[h]="New York City, NY, USA________*4083*N* 7393*W";
h++;cit[h]="Newcastle-on-Tyne, England____*5497*N*  162*W";
h++;cit[h]="Odessa, Ukraine_______________*4645*N* 3080*E";
h++;cit[h]="Osaka, Japan__________________*3453*N*13550*E";
h++;cit[h]="Oslo, Norway__________________*5995*N* 1070*E";
h++;cit[h]="Panama City, Panama___________* 897*N* 7953*W";
h++;cit[h]="Paramaribo, Suriname__________* 575*N* 5525*W";
h++;cit[h]="Paris, France_________________*4880*N*  233*E";
h++;cit[h]="Perth, Australia______________*3195*S*11587*E";
h++;cit[h]="Plymouth, England_____________*5042*N*  408*W";
h++;cit[h]="Port Moresby, Papua New Guinea* 942*S*14713*E";
h++;cit[h]="Prague, Czech Republic________*5008*N* 1443*E";
h++;cit[h]="Rangoon, Myanmar______________*1683*N* 9600*E";
h++;cit[h]="Reykjav\xEDk, Iceland____________*6407*N* 2197*W";
h++;cit[h]="Rio de Janeiro, Brazil________*2295*S* 4320*W";
h++;cit[h]="Rome, Italy___________________*4190*N* 1245*E";
h++;cit[h]="Salvador, Brazil______________*1293*S* 3845*W";
h++;cit[h]="Santiago, Chile_______________*3347*S* 7075*W";
h++;cit[h]="St. Petersburg, Russia________*5993*N* 3030*E";
h++;cit[h]="S\xE3o Paulo, Brazil_____________*2352*S* 4652*W";
h++;cit[h]="San Francisco, CA, USA________*3777*N*12243*W";
h++;cit[h]="Shanghai, China_______________*3117*N*12147*E";
h++;cit[h]="Singapore, Singapore__________* 123*N*10392*E";
h++;cit[h]="Sofia, Bulgaria_______________*4267*N* 2333*E";
h++;cit[h]="Stockholm, Sweden_____________*5928*N* 1805*E";
h++;cit[h]="Sydney, Australia_____________*3400*S*15100*E";
h++;cit[h]="Tananarive, Madagascar________*1883*S* 4755*E";
h++;cit[h]="Teheran, Iran_________________*3575*N* 5175*E";
h++;cit[h]="Tokyo, Japan__________________*3567*N*13975*E";
h++;cit[h]="Toronto, ON, Canada___________*4365*N* 7934*W";
h++;cit[h]="Tripoli, Libya________________*3295*N* 1320*E";
h++;cit[h]="Troms\xF8, Norway________________*6464*N* 1896*E";
h++;cit[h]="Ushuaia, Argentina____________*5480*S* 6830*W";
h++;cit[h]="Venice, Italy_________________*4543*N* 1233*E";
h++;cit[h]="Veracruz, Mexico______________*1917*N* 9617*W";
h++;cit[h]="Vienna, Austria_______________*4823*N* 1633*E";
h++;cit[h]="Vladivostok, Russia___________*4317*N*13200*E";
h++;cit[h]="Warsaw, Poland________________*5223*N* 2100*E";
h++;cit[h]="Washington DC, USA____________*3889*N* 7701*W";
h++;cit[h]="Wellington, New Zealand_______*4128*S*17478*E";
h++;cit[h]="Z\xFCrich, Switzerland___________*4735*N*  852*E";

numPoints=cit.length;

	for(let j=1;j<numPoints;j++){
		no[j]=j+" "+cit[j].substr(0,30).replaceAll("_","");
		la[j]=Number(cit[j].substr(31,4))/100;
		ns[j]=cit[j].substr(36,1);
		lo[j]=Number(cit[j].substr(38,5))/100;
		ew[j]=cit[j].substr(44,1);
		ds=ds+" "+no[j]+"\n";
		dparanu.innerText=ds;
	}
}


init();


/*

Some Cities of The Earth

The link:

http://jrlazz.eu5.org/anim/cities.html

Thanks to the THREE.js Team !

*/

</script>

</body>
</html>