Min geocaching statistik 2009

2009: 531 Found / Attended (including 9 events and 13 FTF). Total: 1433.
2008: 463 Found / Attended (including 5 events and 7 FTF). Total: 902.
2007: 311 Found / Attended (including 8 events and 9 FTF). Total: 439.
2006: 128 Found / Attended (including 4 events and 1 FTF) since July.

Tisdagstema: 2009

Dagens tisdagstema är 2009. Under året har jag och Kaprifol gjort en stor bedrift: Vandrat genom de svenska fjällen. Kaprifol tisdagstemade det.

Förbättringar av fotokonsten var en stor del av året.

  • Jag skaffade min första systemkamera, Canon EOS 450D.
  • Jag skaffade även ett antal intressanta objektiv.
  • Jag skaffade ett mini tripod och en monopod.
  • Jag trixade med HDR
  • Jag gjorde enklare bildförbättringar (lager, oskarp mask, vitbalanskorrigeringar, urblekning)
  • Jag var amatörfotograf på en idrottsturnering för barn med gott resultat, en del riktigt häftiga bilder därifrån.
  • Många intressanta macro och porträttbilder, ofta med Kaprifol som motiv.

Nämnvärt är det intressanta macroobjektivet Tamron SP AF 90mm F/2.8 Di 1:1 Macro som många av mina finaste bilder är tagna med. Nedan är ett foto från Vargö, taget några dagar efter att vi kommit hem från semestern i fjällen och norrland.

 

Modulus matte underlättat flytt av finalkoordinater

Svarade just på ett mail från ägare med ett ganska vanligt problem; finalen behöver flyttas.


Nemas problemas! Förresten så kan man bygga mysterys/multis på modulus logik ex (K+X+Y+Z) mod 1000. K är en konstant given i cachebeskrivningen, X Y Z är tal gömda på buggar eller delsteg. Måste man ändra placering räcker det att ändra K, alla insamlade värden är fortfarande okej.


UPDATE: Förtydligar lite!
Exempel med 6 siffror:
  • Klassiskt brukar man ange N57 41.abc E011 54.def där abcdef sprids ut i lite olika lådor. Ändras positionen så är alla värderna förmodligen kassa och man måste göra om.
  • Säg att man istället placerar ut X=100100 Y=222222 Z=654321. Först när man hittat alla värden X,Y,Z vet man att summan X+Y+Z=976643. Säg nu att man vill ha koordinaten på 123456, så sätter man K = (1000000 + 123456 – 976643) mod 1000000 = 146813 (la till en miljon bara för att slippa negativa tal). Cachare får räkna ut abcdef = (K+X+Y+Z) mod 1000000 = (146813+100100+222222+654321) mod 1000000 = 123456.
  • ”Mod 1000000” behöver dessutom cachare inte förstå, ägaren behöver bara skrivas nått i stil med ”Add K,X,Y,Z together to get the number M. The last six digits of M are abcdefg
  • Skulle sen cachen behöva flyttas, så behöver man bara räkna ut nytt värde på K, cachares insamlade X,Y,Z värden är fortfarande OK.

ps. google är bra på att räkna modulus-ekvationerna. Bara smacka in (146813+100100+222222+654321) mod 1000000 i sökfälltet så räknar google ut svaret.

Bi-directional If-Modified-Since/Last-Modified caching

Added code to cache between client-proxy as well, so now its caching in two directions: client to proxy and proxy to service endpoint.


<?php
define(”MAXSIZE”, 200*1024);
define(”HTTP_LM”, ”Last-Modified: ”);
define(”HTTP_SUCCESS”, ”HTTP/1.1 200 OK”);
define(”LAST_MODIFIED_EXTENSION”, ”.lastmodified.txt” );

$danger = FALSE;
$danger |= ! eregi(‘^[a-zA-Z0-9]+$’, $_GET[‘x’]);
$danger |= ! eregi(‘^[a-zA-Z0-9]+$’, $_GET[‘y’]);
$danger |= ! eregi(‘^[a-zA-Z0-9]+$’, $_GET[‘z’]);
if($danger) die(”security must prevail at all cost: data validation error!”);

$url = ”http://map.eniro.com/geowebcache/service/tms1.0.0/map/&#8221;.$_GET[‘z’].”/”.$_GET[‘x’].”/”.(pow(2,$_GET[‘z’])-1-$_GET[‘y’]).”.png”;
$file = ‘x’.$_GET[‘x’].’y’.$_GET[‘y’].’z’.$_GET[‘x’].’.png’;
$log = ‘log.txt’;

function download($url,$file,$log) {
if(file_exists($file.LAST_MODIFIED_EXTENSION)) {
$lastmodified = file_get_contents($file.LAST_MODIFIED_EXTENSION);
}

$http_headers = ”;
if(isset($lastmodified)) {
$http_headers .= ‘If-Modified-Since: ‘.$lastmodified . ‘\r\n’;
}
$http_opts = array( ‘method’=>”GET”, ‘timeout’=>10, ‘header’ => $http_headers );


$opts = array( ‘http’=> $http_opts );

file_put_contents($log, print_r($opts, true).”\n”, FILE_APPEND);

$context = stream_context_create($opts);
$data = @file_get_contents($url, FILE_BINARY, $context, 0, MAXSIZE);
file_put_contents($log, print_r($http_response_header,true).”\n”, FILE_APPEND);
if($data==FALSE) {      
return FALSE;
}


$downloadOK = FALSE;
$downloadLM = ””;

foreach ($http_response_header as $value) {
if($value==HTTP_SUCCESS) {
$downloadOK = true;
}
else if (substr($value, 0, strlen(HTTP_LM)) == HTTP_LM) {
$downloadLM = substr($value,strlen(HTTP_LM));
}         
}

file_put_contents($log, ‘downloadOK:’.$downloadOK.’ downloadLM:’.$downloadLM.”\n”, FILE_APPEND);

if($downloadLM) {
file_put_contents($file.LAST_MODIFIED_EXTENSION, $downloadLM);
}

if($downloadOK) {
file_put_contents($file, $data);
return $data;
}

return FALSE;
}


$data = download($url,$file,$log);
if($data==FALSE) {
file_put_contents($log, ”return data from file.\n”, FILE_APPEND);
if(file_exists($file)) {
file_put_contents($log, ”return cached file!\n”, FILE_APPEND);
$data = file_get_contents($file);
}
else {
file_put_contents($log, ”ERROR: cached file did not exist!!!\n”, FILE_APPEND);
die();
}
}
else {
file_put_contents($log, ”return data from download.\n”, FILE_APPEND);
}

$lastmodified = file_get_contents($file.LAST_MODIFIED_EXTENSION);
if($lastmodified) {
header(‘Last-modified: ‘ . $lastmodified);
}
if (@strtotime($_SERVER[‘HTTP_IF_MODIFIED_SINCE’]) == @strtotime($lastmodified)) {
file_put_contents($log, ”Client allready has latest file. Don’t send any data.\n”, FILE_APPEND);
header(”HTTP/1.1 304 Not Modified”);
die();
}

header(”Content-type: image/png”);
header(‘Content-Length: ‘ . strlen($data) );
ob_clean();
flush();
echo $data;
die();
?>


Pretty nifty, eh?

PHP server-side caching of file() ‘web service’ calls using Last-modified

Extended upon others work to enhance GC Live experiences in Sweden.

My changes;

  • Input data validation; abort upon malformed data to preserve security
  • Implemented Last-modified/If-Modified-Since caching to reduce load and bandwidth on external
  • Making it nifty! 🙂


<?php
define(”MAXSIZE”, 200*1024);
define(”HTTP_LM”, ”Last-Modified: ”);
define(”HTTP_SUCCESS”, ”HTTP/1.1 200 OK”);
define(”LAST_MODIFIED_EXTENSION”, ”.lastmodified.txt” );

$danger = FALSE;
$danger |= ! eregi(‘^[a-zA-Z0-9]+$’, $_GET[‘x’]);
$danger |= ! eregi(‘^[a-zA-Z0-9]+$’, $_GET[‘y’]);
$danger |= ! eregi(‘^[a-zA-Z0-9]+$’, $_GET[‘z’]);
if($danger) die(”security must prevail at all cost: data validation error!”);

$url = ”http://map.eniro.com/geowebcache/service/tms1.0.0/map/&#8221;.$_GET[‘z’].”/”.$_GET[‘x’].”/”.(pow(2,$_GET[‘z’])-1-$_GET[‘y’]).”.png”;
$file = ‘x’.$_GET[‘x’].’y’.$_GET[‘y’].’z’.$_GET[‘x’].’.png’;
$log = ‘log.txt’;

function download($url,$file,$log) {
if(file_exists($file.LAST_MODIFIED_EXTENSION)) {
$lastmodified = file_get_contents($file.LAST_MODIFIED_EXTENSION);
}

$http_headers = ”;
if(isset($lastmodified)) {
$http_headers .= ‘If-Modified-Since: ‘.$lastmodified . ‘\r\n’;
}
$http_opts = array( ‘method’=>”GET”, ‘timeout’=>10, ‘header’ => $http_headers );


$opts = array( ‘http’=> $http_opts );

file_put_contents($log, print_r($opts, true).”\n”, FILE_APPEND);

$context = stream_context_create($opts);
$data = @file_get_contents($url, FILE_BINARY, $context, 0, MAXSIZE);
file_put_contents($log, print_r($http_response_header,true).’\n’, FILE_APPEND);
if($data==FALSE) {      
return FALSE;
}


$downloadOK = FALSE;
$downloadLM = ””;

foreach ($http_response_header as $value) {
if($value==HTTP_SUCCESS) {
$downloadOK = true;
}
else if (substr($value, 0, strlen(HTTP_LM)) == HTTP_LM) {
$downloadLM = substr($value,strlen(HTTP_LM));
}         
}

file_put_contents($log, ‘downloadOK:’.$downloadOK.’ downloadLM:’.$downloadLM.”\n”, FILE_APPEND);

if($downloadLM) {
file_put_contents($file.LAST_MODIFIED_EXTENSION, $downloadLM);
}

if($downloadOK) {
file_put_contents($file, $data);
return $data;
}

return FALSE;
}


$data = download($url,$file,$log);
if($data==FALSE) {
file_put_contents($log, ”return data from file.\n”, FILE_APPEND);
if(file_exists($file)) {
file_put_contents($log, ”return cached file!\n”, FILE_APPEND);
$data = file_get_contents($file);
}
else {
file_put_contents($log, ”ERROR: cached file did not exist!!!.\n”, FILE_APPEND);
die();
}
}
else {
file_put_contents($log, ”return data from download.\n”, FILE_APPEND);
}
header(”Content-type: image/png”);
header(‘Content-Length: ‘ . strlen($data) );
ob_clean();
flush();
echo $data;
die();
?>


.