Simple Location Version 4.0.0 Released

The Simple Location plugin adds location support to WordPress posts, users, and comments.

Version 4.0.0 adds/rewrites a lot of the plugin.

  • The timezone handling functions were updated to use backported versions of functionality introduced for WordPress 5.3.
  • Fixes related to when WordPress’s default timezone is set to a UTC offset over a timezone string. This only works if the site is running PHP5.5 or greater.
  • Add support for WeatherBit as a weather provider
  • Add support for LocationIQ as a geo and map provider
  • APIXU is now WeatherStack
  • Add elevation support to geonames provider
  • Improve sunrise and sunset functions to account for elevation and introduce new class to handle astronomical functions…plan in future to add additional for weather purposes.
  • Improve Settings page and settings page text. Page is now tabbed.
  • Add airport weather widget and refresh airport data.
  • Last Seen Widget now optionally shows local time, sunrise/sunset times and map.
  • Comments are now adjusted with the timezone of the post they are attached to.
  • Nominatim geo provider now gets admin email as required by the service
  • Timezone overrides are cached.
  • A completely redesigned settings page
  • Previously, maps were set based on width and height, now width and aspect ratio. There are several presets there. This allows for the introduction of responsive images in the future.
  • Enhanced styles for HERE Maps
  • The default map zoom level for a post will be automatically adjusted based on altitude or the accuracy of the GPS information.
  • Adding /map to a WordPress archive page will load a custom template called map-template.php, which will show all of the locations in that archive on a map, along with a location list. The map-template.php file can be added to any theme to override this.
  • The timestamp data extracted from attachments is now adjusted for the correct timezone based on the picture location if set.
  • The creation timestamp of media is now displayed if set on the media modal and edit attachment admin screens.
  • The location is now displayed on the media modal.
  • Historic location lookup in supported location providers(currently only compass). This means when you set the publish date to the past in the Classic Editor or in Micropub, it will look up the historic location if this functionality is available. Not currently in Gutenberg.
  • Default Map Zoom settings now describe scale(City, Town, Village) instead of using Zoom number levels.
  • You can now update the location of a user using geojson over the REST API, allowing it to be automatically updated by an external service.
  • Compass as a location provider can be set on a per user basis, instead of globally.
  • Weather is no longer added if the publish time is not recent. Will look into historic weather in a future update.
  • Misc bug fixes and validation checks.

Converting Google Location History into GeoJSON for Compass

After a lot of procrastinating, I finally decided to import all of my Google Location History into Compass. This meant I had to convert Google’s export format into Compass’s GeoJSON.

A few notes

  • timeStampMs is the timestamp in milliseconds.  Most functions use the timestamp as seconds, so this needed to be converted into an ISO8601 date format.
  • latitudeE7 and longitudeE7 are the coordinates, and must be divided by 1e7 in order to get the more conventional format. Also, there was an issue where some of the numbers were incorrectly exported, so there is a sanity check on that below
  • accuracy is, as suggested, the accuracy of the location
  • Finally, there is activity. I considered doing more with this, but I’m just storing it. Will explain why below the example of my simple PHP code to export.
json = json_decode( $file, true );
$json = $json['locations'];
foreach( $json as $item ) {
	$date = date_create_from_format( 'U', round( $item['timestampMs'] / 1000 ) );
	if ( $item['latitudeE7'] > 900000000 ) {
		$item['latitudeE7'] = $item['latitudeE7'] - 4294967296;
	}
	if ( $item['longitudeE7'] > 900000000 ) {
		$item['longitudeE7'] = $item['longitudeE7'] - 4294967296;
	}
	$output = array(
		'locations' => array(
			array(
				'type' => 'Feature',
				'geometry' => array(
					'type' => 'Point',
					'coordinates' => array(
						( $item['longitudeE7'] / 1e7 ),
						( $item['latitudeE7'] / 1e7 )
					)
				),
				'properties' => array(
					'timestamp' => $date->format( DATE_W3C ),
					'horizontal_accuracy' => $item['accuracy']
				)
			)
		)
	);
				
	if ( array_key_exists( 'activity', $item ) ) {
		$output['locations'][0]['properties']['activity'] = $item['activity'];
	}

For activity, it only appears on some entries, and is for the most part, accurate enough..

  "activity" : [ {
        "type" : "IN_VEHICLE",
        "confidence" : 100
      }

It notes the type of activity, and the confidence level.   However, in this example…

  "activity":[ 
    {"type":"UNKNOWN","confidence":50},          
    {"type":"ON_FOOT","confidence":36}, 
    {"type":"ON_BICYCLE","confidence":11},  
    {"type":"IN_VEHICLE","confidence":2}
  ]

In this example, Google thinks I am either doing something unknown, walking, riding, or on a bicycle. I promise, never a bicycle. So, for now, I consider the information to be less than useful, but am storing it for future use only.

Looking forward to using the data in interesting ways.

Airplane Wifi Location Tracking to Tasker to Compass

On my recent trip, I took Southwest Airlines for the first time in many years. At Indiewebcamp New Haven, I set up Aaron Parecki’s compass project to send my location data to. I have 59MB of location data since March 3oth, 2019.

The problem is transforming the input from Southwest into the format another system can accept. I did not want to write an Android app for this…I wish there was one.

So, instead I used Tasker,  an automation app for Android that does have scripting in it.

So, if you retrieve http://getconnected.southwestwifi.com/current.json, you get the following JSON data.

 {
  "pcent_flt_complete": 0,
  "altVal": "-24",
  "lon": "-73.867",
  "satcomm_status": {
    "commlink": "active",
    "linkparams": "not-stale"
  },
  "dtzone": "CDT",
  "within_us": true,
  "etad": "09:20 AM",
  "lat": "40.775",
  "gspdVal": "10",
  "ttgc": "2h 15m",
  "dist_remain": "888",
  "actime24": "07:05"
}

The Task I created consists of three actions. It uses the HTTP Request action to get the above JSON. Then it uses the below JavaScriptlet(Tasker allows you to write JavaScript, to convert the data into the GeoJSON that Compass expects. The third action posts that to Compass.

var parsed = JSON.parse( http_data );
var gmt = new Date().toISOString();
var alt = Math.round( parsed.altVal * 0.305 );
var feature = {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [parsed.lon, parsed.lat, alt]
      },
      "properties": {
        "timestamp": gmt,
        "percent_complete": parsed.pcent_flt_complete,
         "dist_remain": parsed.dist_remain,
         "source": "flight",
         "airline": "wn"
      }
    };
var compass = { "locations": [feature] };
var featurejson = JSON.stringify( compass );

Now, I am known for not doing much JavaScript work, preferring PHP. But this was simple enough. I could have added more of their parameters, or, since Southwest does not put the flight number into their JSON, allow it to be set.

It is triggered when I am connected to SouthwestWifi, in Airplane Mode, and every 5 minutes. I wasn’t sure if I should poll more often, but 5 minute intervals seemed reasonable. Regrettably, Southwest does not provide more parameters like speed.

I wish some developer would write an app that would do this, partially because, if the wifi goes down, the request will fail and I’ll lose it. I’d rather cache and retry. Also, GPS Logger has some limitations. I wish there was an Android version of Aaron Parecki’s Overland app. Being as he wrote Compass, it works well with that and has those caching features.

I have two flights on two different airlines in the next month, and will see if I can write similar scripts. I enjoy the challenge of trying to write and test it on my phone live.

Next, I need something to display a visualization of this with altitude.

Indieweb Thoughts Post State of the Word

It has been a while since I wrote out some thoughts on where the Indieweb is on WordPress. Sitting here, after hearing Matt Mullenweg gave the State of the Word at WordCamp US, and after I assisting Tantek Çelik in his talk on Taking Back the Web, which was one of the contributing factors to my being at WordCamp US.

I joined the Indieweb community in 2014, and I feel after 5 years of work, things started to come together. We have a robust collection of plugins and opportunities. But over the coming months, there are some long term goals that need to be achieved.

  • The WordPress Block Editor – It is, whether I like it or not, the editor for WordPress is now Gutenberg. The Indieweb plugins currently avoid that reality. I made an effort to make sure that several of them would work with Gutenberg, despite not being Gutenberg ready, but I will have to bite the bullet and learn how to think in blocks.
  • The Webmention and Semantic Linkbacks plugin merge – This has been a slow process. It is holding up or delaying further iteration on the feature set…including things such as improved display.
  • IndieAuth – Improving and hardening the security of the IndieAuth plugin to prepare for AutoAuth and private post support. This requires some additional refactoring.
  • Indieweb Site Health Checker in the Indieweb Plugin – This would parse a site and check its MF2, similar to indiewebify.me

There are obviously other things I’d like to do…improve Micropub for one. but the above are the ones that I think would push things forward the most.

WordPress Webmentions Plugin Version 4.0.0 Released

It has been a long while since a major release of webmentions, and it is not the end of the plans we have. It is merely the first step.

In the lastest version, several useful features were added.

  • Instead of an option to enable webmention support for pages, the plugin now let’s you select the option to declare support for any public post type. This means, by default, you can add support to Media(attachments)
  • For outgoing webmentions, the plugin will now only send actual links, not plaintext URLs in content. It will not send webmentions for media files linked to in img tags or such unless you set this setting. Most sites don’t support receiving them directly to the file anyway.
  • Avatar Support was previously handled by the Semantic Linkbacks plugin. A new implementation of this was added to this plugin and a version of Semantic Linkbacks will be released that will disable its handling if this is enabled.
  • The new avatar support allows for either a URL or an attachment ID.
  • For webmentions without an email address, it will serve a local anonymous avatar(a copy of the WordPress default avatar) rather than asking for one from Gravatar.
  • If there is an email address, it will cache whether there is a gravatar for a defined period of time…defaultly one week and if not serve the local file as well. This reduces unneeded calls to gravatar.
  • Webmention endpoint headers are now only available on URLs on the site that support them. You can disable this and show on all pages. Caching has been enabled to ensure this doesn’t slow page load.
  • Misc improvements to the settings and metadata templates in the admin.

This is all part of a longer project to migrate features from Semantic Linkbacks over to Webmentions. But both plugins are several years old, and therefore it will take time to do it right. The goal is to upgrade, improve, and sometimes completely rewrite each part as it comes over, rather than merge the older code together and fix some of the issues subsequently.

The minimum PHP version for Webmentions is now PHP5.4, to accommodate the current official minimum of PHP-MF2, which will be merged in future when the microformats parsing is migrated to this plugin.