actualización 15feb2018: ver este elemento de libro de cocina para una manera más fácil
actualización 10 abr2018: ver Bryan's guion para un enfoque moderno
Memoria Temprana
Cuando tenía casi tres años, mi papá, W4FNB, SK, me dejó pasar el rato en la sala de radio mientras escuchaba la señal de Sputnik .Lo recuerdo explicando cómo el cambio doppler requería que él ajustara continuamente la sintonía en el Hammarlund receptor HQ-129X , y cómo era importante que el receptor se calentara durante varias horas para estabilizar los osciladores internos de la radio.Creo que también trató de mostrarme algo en el cielo, pero pasarían otros cuatro años antes de que la enfermera de la escuela se diera cuenta de lo mucho que necesitaba anteojos.Sonidos de los Primeros Satélites
Más recientemente
El Estación Espacial Internacional ha estado en órbita desde 1998 o 2000. Esta publicación presentó a JSL para obtener la ubicación actual de la ISS y trazarla en un mapa creado a partir de otra imagen de la NASA.Modifiqué un poco el JSL e hice un video que mostraba un par de días de órbitas de 90 minutos en menos de un minuto.
Algunas mejoras pero bastante similares.Me equivoqué con los nombres de los archivos al no completar los ceros iniciales que Licuadora espera; Usé JSL para cambiar el nombre de los archivos.
// code repaired 15feb2018, requires JMP 11 or later
// trimmed down JSON parser (go get the real one, there is more support for tables)
/*
* JSL JSON Parser, Xan Gregg, 2014-12-29
* pattern matching speedup, Craige Hales, 2015-01-01
*/
New Namespace( "JSON" );
JSON:Char Escape = Function( {c},
Match( c, "\!"", "\!"", "b", "\!u0008", "f", "\!u000C", "n", "\!u000A", "r", "\!u000D", "t", "\!u0009", c )
);
JSON:Unicode Escape = Function( {u},
u = "\!"\!\!u" || u || "\!"";
Parse( u );
);
JSON:Pattern Name = "\!"" // leading quotation mark
+ Pat Test(
value = "";
1;
) // init string accumulator
+ Pat Repeat(
(Pat Break( "\!\\!"" ) >> temp + Pat Test(
value ||= temp;
1;
)) // run of characters that are not \ or "
| ("\u" + Pat Len( 4 ) >> temp + Pat Test(
value ||= JSON:Unicode Escape( temp );
1;
)) // \uXXXX
| ("\" + Pat Len( 1 ) >> temp + Pat Test(
value ||= JSON:Char Escape( temp );
1;
)) // \", for example...embedded quotation mark
) + "\!""; // trailing quotation mark
JSON:Pattern Number = Pat Span( "0123456789-+eE." ) >> temp + Pat Test(
value = Num( temp );
1;
);
JSON:PatternParse = Pat Pos( 0 ) + Pat Repeat(
Pat Pos( /* remember how far we parsed for error message */ ) >> failpos// /* comment out this line for a little more speed */+pattest(if(tickseconds()-lasttime>1,lasttime=tickseconds();wait(0));1)
+ Pat Fence( /* fence off previously parsed text...ain't no going back */ ) + (Pat Regex( "\s*" ) // ignore whitespace
| JSON:Pattern Name | (":" + Pat Test(
key = value;
1;
)) | JSON:Pattern Number | ("true" + Pat Test(
value = 1;
1;
)) | ("false" + Pat Test(
value = 0;
1;
)) | ("null" + Pat Test(
value = .;
1;
)) | ("[" + Pat Test(
Insert Into( stack, {{}}, 1 );
value = Empty();
1;
)) | ("{" + Pat Test(
Insert Into( stack, Associative Array(), 1 );
value = Empty();
Insert Into( keys, key, 1 );
1;
)) | ("]" + Pat Test(
If( !Is Empty( value ),
Insert Into( stack[1], value, 1 /*needs reverse later*/ )
);
value = stack[1];
value = Reverse( value );
Remove From( stack, 1 );
1;
)) | ("}" + Pat Test(
If( !Is Empty( value ),
stack[1][key] = value
);
value = stack[1];
Remove From( stack, 1 );
key = keys[1];
Remove From( keys, 1 );
1;
)) | ("," + Pat Test(
If( Is List( stack[1] ),
Insert Into( stack[1], value, 1 /*needs reverse later*/ ),
stack[1][key] = value
);
value = Empty();
1;
)))
) + Pat R Pos( 0 );
JSON:jsonParse = Function( {json},
{stack = {}, keys = {}, key = "", value = Empty(), temp = 0, totalLen = Length( json ), failpos = 0},
If( !Try( Pat Match( json, JSON:PatternParse ), 0 ),
Throw( "unrecognized JSON at " || Char( failpos ) )
);
value;
);
// end namespace
lat = J( 3600, 1, . ); // trail of previous points, you can make it longer
lon = J( N Rows( lat ), 1, . );
idx = 1;
cur = idx;
error = "";
time = "";
dir = "D:\directory\ISS\m";
seq = 0;
/* open-notify.org (Thanks!) returns JSON data like this:
{
"iss_position": {
"latitude": 24.94415308475734,
"longitude": 116.70173230986174
},
"message": "success",
"timestamp": 1462990726
}
*/
updateLatLon = Function( {},
{where = Try(
loadtextfile( "http://api.open-notify.org/iss-now.json?" || Char( Random Integer( 1, 1e6 ) ) )
//Open( "http://api.open-notify.org/iss-now.json?" || Char( Random Integer( 1, 1e6 ) ) )
, "" ), // fetch a JSON string
locationData = JSON:jsonParse( where ) // use XAN's parser
},
If( !Is Empty( locationData ) & locationData["message"] == "success",
error = ""; // clear any previous message
lat[idx] = Num( locationData["iss_position"]["latitude"] ); // get the two numbers
lon[idx] = Num( locationData["iss_position"]["longitude"] ); // used in the script below to plot a point
time = locationData["timestamp"]; // unix time, not JMP time
time = Format( 1jan1970 + time, /*"ddMonyyyyh:m:s"*/ "yyyy-mm-ddThh:mm:ss" ) || " GMT";
cur = idx;
idx++;
If( idx > N Rows( lat ),
idx = 1
);
,
error = "no location data available"
);
Try(
g << inval;
Wait( 1 );
seq++;
g[framebox( 1 )] << savepicture( dir || Char( seq ) || ".png", "png" );
); // if the map exists, update it.
Schedule( 28, updateLatLon() ); // schedule this function to run again. it would be rude to ask for updates much faster than this.
);
updateLatLon(); // bootstrap call, then it calls itself every 30 seconds
earthLight = Open( "http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg", "jpg" );
{width, height} = earthLight << size; // need the ratio for the frame size...
New Window( "NASA's Night Light Map",
g = Graph Box(
framesize( width / 2, height / 2 ),
X Scale( -180, 180 ),
Y Scale( -90, 90 ),
Text Color( "white" );
Text( {0, -50}, error );
Text( {-150, -88}, time );
Text( {-179, 80}, "International Space Station" );
Text( RightJustified, {160, -88}, "http://visibleearth.nasa.gov" ); // credits
Text( {-50, -88}, "http://open-notify.org/Open-Notify-API/ISS-Location-Now/" ); // credits
//Marker Size( 2 ); Marker( Combine States( Color State( "RED" ), Marker State( 12 ) ), lon, lat ); // space station trail
//Marker Size( 4 ); Marker( Combine States( Color State( "RED" ), Marker State( 12 ) ), {lon[cur], lat[cur]} ); // head
bright = N Rows( lon );
Marker Size( 4 );
For( i = cur, i >= 1, i--,
Marker( Combine States( Color State( RGB Color( bright / N Rows( lon ), 0.1, 0.1 ) ), Marker State( 12 ) ), {lon[i], lat[i]} );
bright--;
Marker Size( 2 );
);
For( i = N Rows( lon ), i > cur, i--,
Marker( Combine States( Color State( RGB Color( bright / N Rows( lon ), 0.1, 0.1 ) ), Marker State( 12 ) ), {lon[i], lat[i]} );
bright--;
);
)
);
frameBox = g[framebox( 1 )]; // the framebox, in the graphbox, is just inside the axes
frameBox << Background Map( Boundaries( "World" ) ); // add boundaries first; they wind up on top of the next bitmap...
g[axisbox( 1 )] << Scale( "Linear" ) << remove axis label; // the geo coordinates were set when the map was added, but
g[axisbox( 2 )] << Scale( "Linear" ) << remove axis label; // we need linear coords to line up the map...
frameBox << AddImage( Image( earthLight ), bounds( Left( -180 ), Right( 180 ), top( 90 ), bottom( -90 ) ) ); // -180..180 seems correct
imgSeg = frameBox << FindSeg( PictSeg( 1 ) ); // the most recently added one is first
imgSeg << lock( 1 ); // and lock it so mouse won't move it by mistake
frameBox << xaxis( show major ticks( false ), show minor ticks( false ), show labels( false ) );
frameBox << yaxis( show major ticks( false ), show minor ticks( false ), show labels( false ) );