r64204 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r64203‎ | r64204 | r64205 >
Date:01:38, 26 March 2010
Author:jeroendedauw
Status:deferred
Tags:
Comment:
Changes for 0.5.6 - rewriting coordinate validation and parsing
* Rmoved parsing done in SMGeoCoordsValue, now replaced by using MapsCoordinateParser
* (Re)moved a bunch of lang keys
Modified paths:
  • /trunk/extensions/SemanticMaps/GeoCoords/SM_GeoCoordsValue.php (modified) (history)
  • /trunk/extensions/SemanticMaps/SemanticMaps.i18n.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMaps/GeoCoords/SM_GeoCoordsValue.php
@@ -26,30 +26,19 @@
2727 * @author Jeroen De Dauw
2828 *
2929 * @ingroup SemanticMaps
30 - *
31 - * TODO: this class should be integrated with Maps's handling of coordinates, as not to have redundant code.
3230 */
3331 class SMGeoCoordsValue extends SMWDataValue {
3432
35 - protected $m_N = false; // cache for localised direction labels
36 - protected $m_E = false; // cache for localised direction labels
37 - protected $m_W = false; // cache for localised direction labels
38 - protected $m_S = false; // cache for localised direction labels
 33+ protected $mCoordinateSet;
 34+ protected $mWikivalue;
3935
40 - protected $m_wikivalue;
41 - protected $m_lat; // decimal latitude of current value
42 - protected $m_long; // decimal longitude of current value
43 - protected $m_latparts; // latitude array of four entries: degrees, minutes, seconds, direction
44 - protected $m_longparts; // longitude array of four entries: degrees, minutes, seconds, direction
45 - // Note: signs are used as e.g. on Google maps, i.e. S and W are negative numbers.
46 -
4736 /**
4837 * Adds support for the geographical coordinate data type to Semantic MediaWiki.
4938 *
5039 * TODO: i18n keys still need to be moved
5140 */
52 - function InitGeoCoordsType() {
53 - SMWDataValueFactory::registerDatatype( '_geo', 'SMGeoCoordsValue', 'Geographic coordinate' );
 41+ public static function InitGeoCoordsType() {
 42+ SMWDataValueFactory::registerDatatype( '_geo', __CLASS__, 'Geographic coordinate' );
5443 return true;
5544 }
5645
@@ -57,7 +46,20 @@
5847 * @see SMWDataValue::parseUserValue
5948 */
6049 protected function parseUserValue( $value ) {
61 - return $this->parseUserValueOrQuery( $value, false );
 50+ if ( $value == '' ) {
 51+ $this->addError( wfMsg( 'smw_novalues' ) );
 52+ } else {
 53+ $coordinates = MapsCoordinateParser::formatCoordinates( $value );
 54+ if ( $coordinates ) {
 55+ $this->mCoordinateSet = $coordinates;
 56+
 57+ if ( $this->m_caption === false ) {
 58+ $this->m_caption = $value;
 59+ }
 60+ } else {
 61+ $this->addError( wfMsgExt( 'maps_unrecognized_coords', array( 'parsemag' ), $value, 1 ) );
 62+ }
 63+ }
6264 }
6365
6466 /**
@@ -67,162 +69,26 @@
6870 * @return SMGeoCoordsValueDescription
6971 */
7072 public function getQueryDescription( $value ) {
71 - return $this->parseUserValueOrQuery( $value, true );
72 - }
73 -
74 - /**
75 - * TODO: support $isQuery=true
76 - */
77 - protected function parseUserValueOrQuery( $value, $isQuery ) {
78 - if ( $value == '' ) {
79 - $this->addError( wfMsg( 'smw_novalues' ) );
80 - return $isQuery ? new SMWThingDescription() : true;
81 - }
82 -
83 - $this->m_lat = false;
84 - $this->m_long = false;
85 - $this->m_latparts = false;
86 - $this->m_longparts = false;
87 - $this->m_wikivalue = $value;
88 -
89 - // Normalize the notation.
90 - $this->initDirectionLabels();
91 - $value = str_replace( array( ' ', $this->m_N, $this->m_E, $this->m_W, $this->m_S, ),
92 - array( ' ', 'N', 'E', 'W', 'S' ), $value );
93 - $value = str_replace( array( '°', '°' ), '°', $value );
94 - $value = str_replace( array( '´', '´' ), '´', $value );
95 - $value = str_replace( array( '″', '″', "''", '"', '´´', SM_GEO_MIN . SM_GEO_MIN ), SM_GEO_SEC, $value );
96 - $value = str_replace( array( '′', '′', "'", '´' ), SM_GEO_MIN, $value );
97 -
98 - // Split the value string.
99 - $parts = preg_split(
100 - '/\s*(°|' . SM_GEO_MIN . '|' . SM_GEO_SEC . '|N|E|W|S|;)\s*/u',
101 - str_replace( ', ', ';', $value ) . ';',
102 - - 1,
103 - PREG_SPLIT_DELIM_CAPTURE
104 - );
105 - $curnum = false;
106 - $angles = array( false, false, false ); // Temporary values for deg, min, sec
107 -
108 - foreach ( $parts as $part ) {
109 - switch ( $part ) {
110 - case '°':
111 - if ( ( $angles[0] !== false ) && ( $this->m_lat === false ) ) { // work off values found earlier
112 - $this->setAngleValues( 'N', $angles );
113 - } // else: we do not accept interchange of order (lat must be first), so there are just too many °s
114 - if ( $curnum !== false ) {
115 - $angles[0] = $curnum;
116 - $curnum = false;
117 - } else {
118 - $this->addError( wfMsgForContent( 'semanticmaps_lonely_unit', $part ) );
119 - }
120 - break;
121 - case SM_GEO_MIN:
122 - if ( ( $curnum !== false ) && ( $angles[1] === false ) ) {
123 - $angles[1] = $curnum;
124 - if ( $angles[0] === false ) $angles[0] = 0;
125 - $curnum = false;
126 - } else {
127 - $this->addError( wfMsgForContent( 'semanticmaps_lonely_unit', $part ) );
128 - }
129 - break;
130 - case SM_GEO_SEC:
131 - if ( ( $curnum !== false ) && ( $angles[2] === false ) ) {
132 - $angles[2] = $curnum;
133 - if ( $angles[0] === false ) $angles[0] = 0;
134 - if ( $angles[1] === false ) $angles[1] = 0;
135 - $curnum = false;
136 - } else {
137 - $this->addError( wfMsgForContent( 'semanticmaps_lonely_unit', $part ) );
138 - }
139 - break;
140 - case 'N': case 'S': // interpret findings as latitude
141 - if ( $curnum !== false ) { // work off number without °
142 - if ( $angles[0] !== false ) { // "12° 34" as coordinate, complain
143 - $this->addError( wfMsgForContent( 'semanticmaps_bad_latlong' ) );
144 - break;
145 - } else {
146 - $angles[0] = $curnum;
147 - $curnum = false;
148 - }
149 - }
150 - if ( ( $this->m_lat === false ) && ( $angles[0] !== false ) ) {
151 - $this->setAngleValues( $part, $angles );
152 - } else {
153 - $this->addError( wfMsgForContent( 'semanticmaps_bad_latlong' ) );
154 - }
155 - break;
156 - case 'E': case 'W': // interpret findings as longitude
157 - if ( $curnum !== false ) { // work off number without °
158 - if ( $angles[0] !== false ) { // "12° 34" as coordinate, complain
159 - $this->addError( wfMsgForContent( 'semanticmaps_bad_latlong' ) );
160 - break;
161 - } else {
162 - $angles[0] = $curnum;
163 - $curnum = false;
164 - }
165 - }
166 - if ( ( $this->m_long === false ) && ( $angles[0] !== false ) ) {
167 - $this->setAngleValues( $part, $angles );
168 - } else {
169 - $this->addError( wfMsgForContent( 'semanticmaps_bad_latlong' ) );
170 - }
171 - break;
172 - case ';': // interpret findings as latitude
173 - if ( $curnum !== false ) { // work off number without °
174 - if ( $angles[0] !== false ) { // "12° 34" as coordinate, complain
175 - $this->addError( wfMsgForContent( 'semanticmaps_bad_latlong' ) );
176 - break;
177 - } else {
178 - $angles[0] = $curnum;
179 - $curnum = false;
180 - }
181 - }
182 - if ( ( $this->m_lat === false ) && ( $angles[0] !== false ) ) {
183 - $this->setAngleValues( 'N', $angles );
184 - } // else: ignore ";" without complaining
185 - break;
186 - case '': break; // ignore
187 - default: // should be a number (if not, errors appear elsewhere)
188 - // no kiloseps in coordinates, use as decsep as a convenience to some users (Bug 11808):
189 - $curnum = str_replace( wfMsgForContent( 'smw_kiloseparator' ), wfMsgForContent( 'smw_decseparator' ), $part );
190 - break;
191 - }
192 - }
193 -
194 - if ( ( $this->m_lat !== false ) && ( $this->m_long === false ) && ( $angles[0] !== false ) ) { // no final E or W?
195 - $this->setAngleValues( 'E', $angles );
196 - }
197 -
198 - if ( ( $angles[0] !== false ) || ( $curnum !== false ) ) { // unprocessed chunk, error
199 -
200 - }
201 -
202 - if ( $this->m_caption === false ) {
203 - $this->m_caption = $value;
204 - }
205 -
206 - if ( $isQuery ) {
207 - return new SMGeoCoordsValueDescription( ); // TODO
208 - } else {
209 - return true;
210 - }
 73+ // TODO
21174 }
21275
21376 /**
21477 * @see SMWDataValue::parseDBkeys
21578 */
21679 protected function parseDBkeys( $args ) {
217 - $this->m_lat = false;
218 - $this->m_long = false;
219 - $this->m_latparts = false;
220 - $this->m_longparts = false;
221 -
222 - list( $this->m_lat, $this->m_long ) = explode( ',', $args[0] );
 80+ list( $this->mCoordinateSet['lat'], $this->mCoordinateSet['lon'] ) = explode( ',', $args[0] );
22381
224 - $this->m_caption = $this->formatAngleValues( true ) . ', ' . $this->formatAngleValues( false ); // this is our output text
225 - $this->m_wikivalue = $this->m_caption;
 82+ $this->m_caption = $this->mCoordinateSet['lat'] . ', ' . $this->mCoordinateSet['lon'];
 83+ $this->mWikivalue = $this->m_caption;
22684 }
 85+
 86+ /**
 87+ * @see SMWDataValue::getDBkeys
 88+ */
 89+ public function getDBkeys() {
 90+ $this->unstub();
 91+ return array( $this->mCoordinateSet['lat'] . ',' . $this->mCoordinateSet['lon'] );
 92+ }
22793
22894 /**
22995 * @see SMWDataValue::getShortWikiText
@@ -231,8 +97,8 @@
23298 if ( $this->isValid() && ( $linked !== null ) && ( $linked !== false ) ) {
23399 SMWOutputs::requireHeadItem( SMW_HEADER_TOOLTIP );
234100 return '<span class="smwttinline">' . $this->m_caption . '<span class="smwttcontent">' .
235 - wfMsgForContent( 'semanticmaps_label_latitude' ) . ' ' . $this->formatAngleValues( true ) . '<br />' .
236 - wfMsgForContent( 'semanticmaps_label_longitude' ) . ' ' . $this->formatAngleValues( false ) .
 101+ wfMsgForContent( 'maps-latitude' ) . ' ' . $this->mCoordinateSet['lat'] . '<br />' .
 102+ wfMsgForContent( 'maps-longitude' ) . ' ' . $this->mCoordinateSet['lon'] .
237103 '</span></span>';
238104 } else {
239105 return $this->m_caption;
@@ -243,7 +109,8 @@
244110 * @see SMWDataValue::getShortHTMLText
245111 */
246112 public function getShortHTMLText( $linker = null ) {
247 - return $this->getShortWikiText( $linker ); // should be save (based on xsdvalue)
 113+ // TODO: parse to HTML?
 114+ return $this->getShortWikiText( $linker );
248115 }
249116
250117 /**
@@ -253,7 +120,7 @@
254121 if ( !$this->isValid() ) {
255122 return $this->getErrorText();
256123 } else {
257 - return $this->formatAngleValues( true ) . ', ' . $this->formatAngleValues( false );
 124+ return $this->mCoordinateSet['lat'] . ', ' . $this->mCoordinateSet['lon'];
258125 }
259126 }
260127
@@ -261,23 +128,16 @@
262129 * @see SMWDataValue::getLongHTMLText
263130 */
264131 public function getLongHTMLText( $linker = null ) {
 132+ // TODO: parse to HTML?
265133 return $this->getLongWikiText( $linker );
266134 }
267135
268136 /**
269 - * @see SMWDataValue::getDBkeys
270 - */
271 - public function getDBkeys() {
272 - $this->unstub();
273 - return array( $this->m_lat . ',' . $this->m_long );
274 - }
275 -
276 - /**
277137 * @see SMWDataValue::getWikiValue
278138 */
279139 public function getWikiValue() {
280140 $this->unstub();
281 - return $this->m_wikivalue;
 141+ return $this->mWikivalue;
282142 }
283143
284144 /**
@@ -293,136 +153,13 @@
294154 }
295155
296156 /**
297 - * Get and cache localised direction labels. Just for convenience.
298 - */
299 - protected function initDirectionLabels() {
300 - $this->m_N = wfMsgForContent( 'semanticmaps_abb_north' );
301 - $this->m_E = wfMsgForContent( 'semanticmaps_abb_east' );
302 - $this->m_W = wfMsgForContent( 'semanticmaps_abb_west' );
303 - $this->m_S = wfMsgForContent( 'semanticmaps_abb_south' );
304 - }
305 -
306 - /**
307 - * Helper function: read a possibly incomplete array of angles for one coordinate.
308 - * The direction is one of N, E, W, S, and $angles is an array of three values,
309 - * each possibly false if unset.
310 - */
311 - protected function setAngleValues( $direction, &$angles ) {
312 - $numvalue = SMWDataValueFactory::newTypeIDValue( '_num' );
313 - $res = 0;
314 - $factor = 1;
315 -
316 - for ( $i = 0; $i < 3; $i++ ) {
317 - if ( $angles[$i] !== false ) {
318 - $numvalue->setUserValue( $angles[$i] );
319 - if ( $numvalue->isValid() && ( $numvalue->getUnit() == '' ) ) {
320 - $res += $numvalue->getNumericValue() / $factor;
321 - } else {
322 - $this->addError( wfMsgForContent( 'smw_nofloat', $angles[$i] ) );
323 - }
324 - }
325 - $factor = $factor * 60;
326 - }
327 -
328 - switch ( $direction ) {
329 - case 'N': $this->m_lat = $res; break;
330 - case 'S': $this->m_lat = - 1 * $res; break;
331 - case 'E': $this->m_long = $res; break;
332 - case 'W': $this->m_long = - 1 * $res; break;
333 - }
334 -
335 - if ( ( ( $direction == 'E' ) || ( $direction == 'W' ) ) &&
336 - ( ( $this->m_long > 180 ) || ( $this->m_long <= - 180 ) ) ) { // bring values back into [180, -180)
337 - $this->m_long += ( $this->m_long < 0 ) ? ( round( abs( $this->m_long ) / 360 ) * 360 ):( round( $this->m_long / 360 ) * - 360 );
338 - }
339 - // TODO: also make such a normalisation for lat ...
340 -
341 - $angles = array( false, false, false );
342 - }
343 -
344 - /**
345 - * Return array with four entries for deg, min, sec, direction,
346 - * that corresponds to the current latitude or longitude.
347 - *
348 - * @param Boolean $lat When true, latitude will be used, otherwise longitude will be.
349 - */
350 - protected function getAngleValues( $lat = true ) {
351 - if ( $lat ) {
352 - if ( $this->m_latparts !== false ) {
353 - return $this->m_latparts;
354 - }
355 - $num = abs( $this->m_lat );
356 - $d = ( $this->m_lat < 0 ) ? 'S':'N';
357 - } else {
358 - if ( $this->m_longparts !== false ) {
359 - return $this->m_longparts;
360 - }
361 - $num = abs( $this->m_long );
362 - $d = ( $this->m_long < 0 ) ? 'W':'E';
363 - }
364 - $result = array( 0, 0, 0, $d );
365 - $result[0] = floor( $num );
366 - $num = ( $num - $result[0] ) * 60;
367 - $result[1] = floor( $num );
368 - $result[2] = ( $num - $result[1] ) * 60;
369 - if ( abs( $result[2] ) < 0.001 ) { // limit precission, avoid conversion generated junk and EXP notation in coords
370 - $result[2] = 0;
371 - }
372 - if ( $lat ) {
373 - $this->m_latparts = $result;
374 - } else {
375 - $this->m_longparts = $result;
376 - }
377 - return $result;
378 - }
379 -
380 - /**
381 - * Format the current latitude or longitude. The parameter $content states
382 - * whether the result is for content printout. Alternatively, a language-
383 - * independent result is generated.
384 - *
385 - * @param Boolean $lat When true, latitude will be used, otherwise longitude will be.
386 - * @param Boolean $content
387 - */
388 - protected function formatAngleValues( $lat = true, $content = true ) {
389 - $values = $this->getAngleValues( $lat );
390 -
391 - if ( $content ) {
392 - $this->initDirectionLabels();
393 - $result = smwfNumberFormat( $values[0] ) . '°' . smwfNumberFormat( $values[1] ) . SM_GEO_MIN .
394 - smwfNumberFormat( $values[2] ) . SM_GEO_SEC;
395 - switch ( $values[3] ) {
396 - case 'N': return $result . $this->m_N;
397 - case 'E': return $result . $this->m_E;
398 - case 'W': return $result . $this->m_W;
399 - case 'S': return $result . $this->m_S;
400 - }
401 - } else {
402 - return smwfNumberFormat( $values[0] ) . '°' . smwfNumberFormat( $values[1] ) . SM_GEO_MIN .
403 - smwfNumberFormat( $values[2] ) . SM_GEO_SEC . $values[3];
404 - }
405 - }
406 -
407 - /**
408157 * Create links to mapping services based on a wiki-editable message. The parameters
409158 * available to the message are:
410159 *
411 - * $1: latitude integer degrees, $2: longitude integer degrees
412 - * $3: latitude integer minutes, $4: longitude integer minutes
413 - * $5: latitude integer seconds, $6: longitude integer seconds,
414 - * $7: latitude direction string (N or S), $8: longitude direction string (W or E)
415 - * $9: latitude in decimal degrees, $10: longitude in decimal degrees
416 - * $11: sign (- if south) for latitude, $12: sign (- if west) for longitude
 160+ *
417161 */
418162 protected function getServiceLinkParams() {
419 - $latvals = $this->getAngleValues( true );
420 - $longvals = $this->getAngleValues( false );
421 - return array( $latvals[0], $longvals[0],
422 - $latvals[1], $longvals[1],
423 - round( $latvals[2] ), round( $longvals[2] ),
424 - $latvals[3], $longvals[3],
425 - abs( $this->m_lat ), abs( $this->m_long ),
426 - $latvals[3] == 'S' ? '-':'', $longvals[3] == 'W' ? '-':'' );
 163+ return array( ); // TODO
427164 }
428165
429166 }
Index: trunk/extensions/SemanticMaps/SemanticMaps.i18n.php
@@ -21,16 +21,6 @@
2222 'semanticmaps_desc' => "Provides the ability to view and edit coordinate data stored through the Semantic MediaWiki extension ([http://wiki.bn2vs.com/wiki/Semantic_Maps demo]).
2323 Available map services: $1",
2424
25 - // Geo coord data type
26 - 'semanticmaps_lonely_unit' => 'No number found before the symbol "$1".', // $1 is something like °
27 - 'semanticmaps_bad_latlong' => 'Latitude and longitude must be given only once, and with valid coordinates.',
28 - 'semanticmaps_abb_north' => 'N',
29 - 'semanticmaps_abb_east' => 'E',
30 - 'semanticmaps_abb_south' => 'S',
31 - 'semanticmaps_abb_west' => 'W',
32 - 'semanticmaps_label_latitude' => 'Latitude:',
33 - 'semanticmaps_label_longitude' => 'Longitude:',
34 -
3525 // Forms
3626 'semanticmaps_lookupcoordinates' => 'Look up coordinates',
3727 'semanticmaps_enteraddresshere' => 'Enter address here',

Follow-up revisions

RevisionCommit summaryAuthorDate
r64205Changes for 0.5.6 - rewriting coordinate validation and parsing...jeroendedauw01:39, 26 March 2010

Status & tagging log