Command line tool written in PHP using the Laravel Framework (v.5.8) and the PHP extension EXIF.
It recursively reads all images, extracts their EXIF GPS data (longitude and latitude) and then writes the name of that image and any GPS co-ordinates it finds to a CSV or HTML file.
- PHP 7.1
- EXIF extension (included by default)
Run composer install
Run php artisan image:extract-geoloc
Optionally a path can be supplied (e.g. php artisan image:extract-geoloc /path/to/dir
).
Default export format is CSV. To export to HTML append the option --export=html
to the command.
Run phpunit
Goal of this implementation is to have a tool that is easy to understand and at the same time easy to extend for future requirements.
- app\Console\Commands : Contains Artisan command that executes the main workflow.
- app\Geolocation : Contains objects that are part of the Geolocation domain (here: Value Object for a GPS Coordinate).
- app\Infrastructure : Contains services for Data Export, Filesystem Access and Image Processing as well as their Adapters for easy integration
- tests : Contains Feature and Unit tests. Feature tests are integration tests, e.g. because they access the filesystem
Injected dependencies for Infrastructure services are Interfaces. The binding to the actual implementations is done via the Laravel Service Container in App\Providers\ExtractImageGeoLocationsServiceProvider.
Includes implementations for export to both CSV and HTML. A new implementation should implement the Exporter interface and a reference be added to config/exporter.php so it is generated by the factory.
By defining all implementations in the config file the factory adheres the the Open/Close principle (it doesn't need to be modified for future extensions).
The HTML exporter is using a Blade template to separate application code and presentation concerns.
FilesystemService provides functionality to scan directories for files and filter out image files. The base for the scanDirectories function was copied and adapted. The list of filenames that should be ignored is injected from a config file (Open/Close principle).
Nothing special here. EXIF makes it fairly easy to extract header data. Some extra care was take to ensure all required header fields are included to prevent exceptions at runtime.
GPS Coordinates from the image files are transformed into Coordinate value objects to add type safety/validation and make further formatting easier.
Storing coordinates as objects makes the handling a lot easier and saver. We can ensure that latitude is only either North or South and longitude either East or West. Further validation could be added to ensure the degrees are within a valid range. Another potential improvement would be to allow building coordinates from different formats.