summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_GeoCoord.php
blob: 208366e62d12a44871e8e18bd9ab83b4bd6b9538 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<?php

use SMW\Exception\DataItemException;

/**
 * @license GNU GPL v2+
 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 */
class SMWDIGeoCoord extends SMWDataItem {

	/**
	 * @var float
	 */
	private $latitude;

	/**
	 * @var float
	 */
	private $longitude;

	/**
	 * @var float|null
	 */
	private $altitude = null;

	/**
	 * Takes a latitude and longitude, and optionally an altitude. These can be provided in 2 forms:
	 * * An associative array with lat, lon and alt keys
	 * * Lat, lon and alt arguments
	 *
	 * The second way to provide the arguments, as well as the altitude argument, where introduced in SMW 1.7.
	 */
	public function __construct() {
		$args = func_get_args();

		$count = count( $args );

		if ( $count === 1 && is_array( $args[0] ) ) {
			if ( array_key_exists( 'lat', $args[0] ) && array_key_exists( 'lon', $args[0] ) ) {
				$this->setLatitude( $args[0]['lat'] );
				$this->setLongitude( $args[0]['lon'] );

				if ( array_key_exists( 'alt', $args[0] ) ) {
					$this->altitude = (float)$args[0]['alt'];
				}
			}
			else {
				throw new DataItemException( 'Invalid coordinate data passed to the SMWDIGeoCoord constructor' );
			}
		}
		elseif ( $count === 2 || $count === 3 ) {
			$this->setLatitude( $args[0] );
			$this->setLongitude( $args[1] );

			if ( $count === 3 ) {
				$this->altitude = (float)$args[2];
			}
		}
		else {
			throw new DataItemException( 'Invalid coordinate data passed to the SMWDIGeoCoord constructor' );
		}
	}

	private function setLatitude( $latitude ) {
		if ( is_int( $latitude ) ) {
			$latitude = (float)$latitude;
		}

		if ( !is_float( $latitude ) ) {
			throw new DataItemException( '$latitude should be a float' );
		}

		$this->latitude = $latitude;
	}

	private function setLongitude( $longitude ) {
		if ( is_int( $longitude ) ) {
			$longitude = (float)$longitude;
		}

		if ( !is_float( $longitude ) ) {
			throw new DataItemException( '$longitude should be a float' );
		}

		$this->longitude = $longitude;
	}

	/**
	 * (non-PHPdoc)
	 * @see SMWDataItem::getDIType()
	 */
	public function getDIType() {
		return SMWDataItem::TYPE_GEO;
	}

	/**
	 * Returns the coordinate set as an array with lat and long (and alt) keys
	 * pointing to float values.
	 *
	 * @return array
	 */
	public function getCoordinateSet() {
		$coords = [ 'lat' => $this->latitude, 'lon' => $this->longitude ];

		if ( !is_null( $this->altitude ) ) {
			$coords['alt'] = $this->altitude;
		}

		return $coords;
	}

	/**
	 * (non-PHPdoc)
	 * @see SMWDataItem::getSortKey()
	 */
	public function getSortKey() {
		return $this->latitude . ',' . $this->longitude . ( $this->altitude !== null ? ','. $this->altitude : '' );
	}

	/**
	 * (non-PHPdoc)
	 * @see SMWDataItem::getSerialization()
	 */
	public function getSerialization() {
		return implode( ',', $this->getCoordinateSet() );
	}

	/**
	 * Create a data item from the provided serialization string and type
	 * ID.
	 * @note PHP can convert any string to some number, so we do not do
	 * validation here (because this would require less efficient parsing).
	 *
	 * @param string $serialization
	 *
	 * @return self
	 */
	public static function doUnserialize( $serialization ) {
		$parts = explode( ',', $serialization );
		$count = count( $parts );

		if ( $count !== 2 && $count !== 3 ) {
			throw new DataItemException( 'Unserialization of coordinates failed' );
		}

		$coords = [ 'lat' => (float)$parts[0], 'lon' => (float)$parts[1] ];

		if ( $count === 3 ) {
			$coords['alt'] = (float)$parts[2];
		}

		return new self( $coords );
	}

	/**
	 * @return float
	 */
	public function getLatitude() {
		return $this->latitude;
	}

	/**
	 * @return float
	 */
	public function getLongitude() {
		return $this->longitude;
	}

	/**
	 * Returns the altitude if set, null otherwise.
	 *
	 * @return float|null
	 */
	public function getAltitude() {
		return $this->altitude;
	}

	public function equals( SMWDataItem $di ) {
		if ( $di->getDIType() !== SMWDataItem::TYPE_GEO ) {
			return false;
		}

		return $di->getSerialization() === $this->getSerialization();
	}
}