SnailLife snail stables have always lived in the ether - in some virtual universe with no physical location. Since I'm trying to make SnailLife based in reality, users' snail stables should also be based in real locations. This is why now, upon registration, the user's physical location is used as the location of their snail stable.
Having never used HTML5 geolocation features before, I kind of winged it and hacked together something that works for now. Currently I get the user's location in two cases - on registration, and when searching for wild snails.
Here is how it happens on the registration page:
<script>
getLocation();
function getLocation() {
console.log('getLocation here');
if (Modernizr.geolocation) {
console.log('geolocation in');
navigator.geolocation.getCurrentPosition(createHiddenInput, geolocationError);
}
else {
console.log('no native support');
}
}
function createHiddenInput(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log('latitude: ' + latitude);
console.log('longitude: ' + longitude);
jQuery(document).ready(function() {
$('#registrationForm').append('<input type="hidden" name="stableLatitude" value=' + latitude + '/>');
$('#registrationForm').append('<input type="hidden" name="stableLongitude" value=' + longitude +'/>');
$('#registrationForm').append('Stable Location: ' + getCityName(latitude, longitude) + ',' + getCountryName(latitude, longitude));
});
}
</script>
Problem - retrieving the location takes a few seconds. If the user happens to register too quickly their location will not be retrieved. As a potential solution I am considering disabling the Submit button until the location is ready...however, what if they don't want to allow me to retrieve their location at all?
If the user does not let me retrieve their location, it will be set by default to some place in Louisiana. Maybe then I can just display a "
Don't want to be in Louisiana? Wait while we get your location!" message...
So the latitude and longitude is stored for the user's new account. Then to get the country and city name when displaying where the user is we use the Geonames API. Example:
public static function GetCityName($latitude, $longitude) {
$cityName = null;
if (Utility::InternetOn()) {
$url = "http://api.geonames.org/findNearbyPlaceName?lat=" . $latitude . "&lng=" . $longitude . "&username=myusername";
Log::info ('connection');
$xmlDoc = new \DOMDocument();
$xmlDoc->load($url);
$cityNameNode = $xmlDoc->getElementsByTagName("name");
$cityName = null;
if ($cityNameNode->length > 0) {
$cityName = $cityNameNode->item(0)->nodeValue;
}
}
return $cityName;
}
Right now in my snail stable it is 15.5 degrees Celsius. I don't think I'm going to simulate building insulation, so without temperature control it would be about the same temperature in each jar (I may take humidity from the jar's substrate into account, and have other items adding warmth or cold aside from temperature control gadgets). The user won't see their
exact jar temperature until they install a thermometer in the jar, and they won't be able to regulate the temperature without installing a temperature controller.
Snail jars have had temperature for a long time, but now that temperature is influenced by real life weather at the stable's location. This will in turn influence the snails within the jar: their health, mood, etc (this last part is not yet implemented...well, it is only implemented very very roughly).
To get temperature I originally tried
OpenWeatherMap but that seems very slow and unreliable. So I am trying out
The Dark Sky API:
public static function GetCurrentTemperature($latitude, $longitude) {
$url = "https://api.forecast.io/forecast/MYAPIKEY/" . $latitude . "," . $longitude;
$JSON = file_get_contents($url);
$data = json_decode($JSON);
$f = $data->currently->temperature;
$c = Utility::FahrenheitToCelsius($f);
return $c;
}
The Dark Sky gives me 1000 free API calls per day. I blew through that in under an hour because I was stupid and calling the API each time I needed to get the temperature. Which is a lot...passive events alone blow through about 200 calls in 5 minutes.
So I added a
currentTemp field in the User table and a
temp_updated_at field. I added a recurring event to update the temperature once per hour.
Different snails will adapt to live better in certain climates, and you will find different kinds of snails in different places. This way if you happen to physically be traveling the world you could hunt for wild snails away from your stable and find totally different patterns, colors, and traits.
Aside from affecting snail health and such in the future, temperature in a jar
already affects how quickly consumable items rot. Things rot faster at a higher temperature.
Up next I want to think of a good way to vary snail types based on coordinates. There will be some manually set snail types that are available only in certain areas of the world if I want to make some super cool rare location (eg - get a special snail if you're at the NASA headquarters!), but for the most part I want to create that variation automatically. I just have to think of a good way to approach this. I might even embed a Google Map on the wild-snail-collection page so that instead of just clicking "Look under a rock" or whatever you can click on a spot in your general vicinity on a map and see what snail pops up there!