Определение геокоординат фотографий на PHP

в 17:31, , рубрики: exif, php, метки: ,

Привет!

Сегодня я расскажу как узнать геопозиции фотографии на PHP. Для этого мы напишем простой скрипт, с помощью которого из метаданных извлечем фотографий геопозиции.

Что за метаданные?

Как многие уже догадались — это данные EXIF. Собственно, в нем и хранится ширина, высота, дата, размер, геопозиция, тип фотографии, свойства камеры и многое другое. В этом списке нам понадобится геопозиция.

Как работать с ним?

Очень просто! Для этого есть специальное расширение для PHP, которая называется exif. Если оно у вас не установлено, то для продолжения следует её установить.

Начнем

Для начало создаем файл index.php, где у нас должна стоять форма для загрузки файла.
В нем пока что пишем простой HTML код.

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Определение геокоординат фотографий на PHP</title>
</head>
<body>
	
	<?php if( isset( $_GET['error'] ) ): ?>
		<!-- Ошибка -->
		<p class="error">
			<?php
			switch ($_GET['error']) {
				case 1: echo "Фотография отсутсвует."; break;
				case 2: echo "Неверный формат."; break;
				case 3: echo "У этой фотографии нету данных о геопозиции. Попробуйте зугрузить другую."; break;
			}
			?>
		</p>
	<?php endif; ?>
	
	<p>Загрузите фотографию в формате jpeg.</p>
	
	<form action="upload.php" method="post" enctype="multipart/form-data">
		<input type="file" name="image"> <br>
		<input type='submit' value="Загрузить!">
	</form>
</body>
</html>

Как видите, тут ничего сложного нету. Простая форма загрузки, которая отправляет данные файлу upload.php. Также я тут написал сообщения об ошибках. Ошибки появляются, если переходить по адресу /index.php?error=1

А потом?

А потом создаем файл upload.php, где и будем обрабатывать данные фотографии, а также показать результат.

<?php

// Если картинка не загружена
if( empty( $_FILES['image'] ) ) {
	// Перенаправляем на главный с ошибкой
	header( 'Location: /?error=1' );
	exit();
}

// Если тип изображения не jpeg
if( $_FILES['image']['type'] !== 'image/jpeg' ) {
	// Перенаправляем на главный с ошибкой
	header( 'Location: /?error=2' );
	exit();
}

Тут мы проверяем, загружен ли файл? Если нет, то перенаправляем на главный с ошибкой. Потом проверяем, совпадает ли формат файла с нужным нам форматом? Если нет, то, опять, перенаправляем на главный с ошибкой. Если все нормально, то идем дальше.

// Будем использовать временный путь к файлу
$img = $_FILES['image']['tmp_name'];

// Получаем данные
$exif = exif_read_data( $img, 0, true );

// Выводим результат
print_r( $exif );

Таким образом, мы получаем все EXIF данные фотографии. Посмотрим что там.

Откройте

[FILE] => Array
(

)

[COMPUTED] => Array
(

)

[IFD0] => Array
(

)

[THUMBNAIL] => Array
(

)

[EXIF] => Array
(

)

[GPS] => Array
(
[GPSLatitudeRef] => N
[GPSLatitude] => Array
(
[0] => 40/1
[1] => 1096/100
[2] => 0/1
)

[GPSLongitudeRef] => E
[GPSLongitude] => Array
(
[0] => 44/1
[1] => 2674/100
[2] => 0/1
)

[GPSTimeStamp] => Array
(
[0] => 7/1
[1] => 2/1
[2] => 2314/100
)

[GPSImgDirectionRef] => T
[GPSImgDirection] => 50207/178
)

Нам из этого списка нужна ветка GPS. Именно там хранятся наши координаты.

Если вы заметили, координаты тут выглядят как-то не очень: они представлены делением. Например:

2674/100 = 26.74

Чтобы они выглядели нормально, в самом начале файла пишем функцию преобразования.

// Получаем координаты из строки
function getCoord( $expr ) {
	$expr_p = explode( '/', $expr );
	return $expr_p[0] / $expr_p[1];
}

Теперь все в порядке. Идем дальше.

// Если ветка GPS отсутствует
if( empty( $exif['GPS'] ) ) {
	// Перенаправляем на главный с ошибкой
	header( 'Location: /?error=3' );
	exit();
}

Уже нам знакомый код: перенаправляем при ошибке.

Теперь переходим к части представления координатов. В том же файле, на самом внизу, после закрытия тэга PHP, пишем HTML код.

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Определение геокоординат фотографий на PHP</title>
</head>
<body>
	<h1>Геокординаты</h1>
	<p>
		Широта: 
		<?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?>
		<?=getCoord( $exif['GPS']['GPSLatitude'][0] )?><sup>o</sup>
		<?=getCoord( $exif['GPS']['GPSLatitude'][1] )?>'
		<?=getCoord( $exif['GPS']['GPSLatitude'][2] )?>''
	</p>
	
	<p>
		Долгота:
		<?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?>
		<?=getCoord( $exif['GPS']['GPSLongitude'][0] )?><sup>o</sup>
		<?=getCoord( $exif['GPS']['GPSLongitude'][1] )?>''
		<?=getCoord( $exif['GPS']['GPSLongitude'][2] )?>'''</p>
</body>
</html>

Тут мы уже выводим результат на экран. В итоге, мы получаем данные геопозиции из фотографии.

Спасибо, что дочитали!

index.php

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Определение геокоординат фотографий на PHP</title>
</head>
<body>
	
	<?php if( isset( $_GET['error'] ) ): ?>
		<!-- Ошибка -->
		<p class="error">
			<?php
			switch ($_GET['error']) {
				case 1: echo "Фотография отсутсвует."; break;
				case 2: echo "Неверный формат."; break;
				case 3: echo "У этой фотографии нету данных о геопозиции. Попробуйте зугрузить другую."; break;
			}
			?>
		</p>
	<?php endif; ?>
	
	<p>Загрузите фотографию в формате jpeg.</p>
	
	<form action="upload.php" method="post" enctype="multipart/form-data">
		<input type="file" name="image"> <br>
		<input type='submit' value="Загрузить!">
	</form>
</body>
</html>

upload.php

<?php

// Получаем координаты из строки
function getCoord( $expr ) {
	$expr_p = explode( '/', $expr );
	return $expr_p[0] / $expr_p[1];
}

// Если картинка не загружена
if( empty( $_FILES['image'] ) ) {
	// Перенаправляем на главный с ошибкой
	header( 'Location: /?error=1' );
	exit();
}

// Если тип изображения не jpeg
if( $_FILES['image']['type'] !== 'image/jpeg' ) {
	// Перенаправляем на главный с ошибкой
	header( 'Location: /?error=2' );
	exit();
}

// Будем использовать временный путь к файлу
$img = $_FILES['image']['tmp_name'];

// Получаем данные
$exif = exif_read_data( $img, 0, true );

// Если ветка GPS отсутсвует
if( empty( $exif['GPS'] ) ) {
	// Перенаправляем на главный с ошибкой
	header( 'Location: /?error=3' );
	exit();
}
?>

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Определение геокоординат фотографий на PHP</title>
</head>
<body>
	<h1>Геокординаты</h1>
	<p>
		Широта: 
		<?=$exif['GPS']['GPSLatitudeRef'] == 'S' ? '-' : '' ?>
		<?=getCoord( $exif['GPS']['GPSLatitude'][0] )?><sup>o</sup>
		<?=getCoord( $exif['GPS']['GPSLatitude'][1] )?>'
		<?=getCoord( $exif['GPS']['GPSLatitude'][2] )?>''
	</p>
	
	<p>
		Долгота:
		<?=$exif['GPS']['GPSLongitudeRef'] == 'W' ? '-' : '' ?>
		<?=getCoord( $exif['GPS']['GPSLongitude'][0] )?><sup>o</sup>
		<?=getCoord( $exif['GPS']['GPSLongitude'][1] )?>''
		<?=getCoord( $exif['GPS']['GPSLongitude'][2] )?>'''</p>
</body>
</html>

При написании этой статьи я прочитал статью в Wikipedia — Geotagging

Автор: m_hamlet

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js