It is difficult to geocode uploaded media on Wikimedia Commons. The existing advice is for the user to go elsewhere to figure out the latitude and longitude appropriate to their photo, then to figure out which representation of latitude and longitude to use (degrees minutes seconds, decimal degrees, or some other format) and finally to encode the latitude and longitude in appropriate wikiText, such as a Location template.

We would like to greatly lower the bar to geocode media on Commons:

use EXIF data contained in the media file to suggest an appropriate location

eliminate the need for the uploader to go outside the upload interface to search a map.

eliminate the need for the uploader to manually edit, or even know about, latitude and longitude.

eliminate the need for the uploader to create, edit, or even know about the location-related wikitext that will be entered onto the File: page for the media file.

This should also:

help regularize the format of the wikitext that is used on Commons to geocode media files.

The desired solution is a JavaScript jQuery plugin which presents a map interface, which can be manipulated to select a particular location, and which can then report that location in code, preferably as wikiText containing a Location template.

The map plugin should not be dependent on any particular maps provider. It should be able to show tiles and interface from Google Maps, Yahoo Maps, and OpenStreetMaps. (This will probably reuse existing work such as the MediaWiki Maps extension.)

This plugin should be able to be integrated directly into the MediaWiki UploadWizard extension. For the most part, as long as it conforms to the Javascript API below, that should happen automatically.

This plugin should be able to show an interface centered at a pre-selected location.

The plugin will be delivered with documentation that describes the interface for creating the widget, how to manipulate the map to change a location, and how to obtain location wikiText.

The plugin should not have any effects on the HTML page or the window's DOM structure, other than within the element selected for it at creation. The plugin should not create any global variables. It should be possible to have multiple widgets on the page (although it is acceptable if we can only have one in "open, editing" state at a time).

The plugin should work on the following browsers, at a minimum: Microsoft Internet Explorer 6 or greater, Mozilla Firefox 3.1 or greater, Apple Safari 3.0 or greater, and Google Chrome 4.0 or greater. Compatibility with Opera 9 or greater is preferred. Some degraded functionality is acceptable for older browsers such as Microsoft Internet Explorer 6.

The plugin should be internationalizable, at least in all messages presented to the user.

The code and other assets for this plugin will be licensed under the same terms as MediaWiki. (The code will be GPL-compatible, the images and other assets will be compatible with a Creative Commons Attribution-ShareAlike Unported 3.0 license.)

Details of decoding EXIF data are dealt with elsewhere; on MediaWiki 1.18 and later properly decoded 'gpslatitude' and 'gpslongitude' entries are made available in the image's metadata dictionary. The calling code elsewhere in UploadWizard will extract these and hand them to the widget. (See the stub prefillLocation() and the already-extant similar prefillDate() in mw.UploadWizardDetails.js for where to start plugging.)

All the map widget has to do is be able to select a location based on the provided latitude and longitude.

Here are some rough docs on Location widget use cases. They help explain why it isn't just a simple map. We also need to recover from mistakes, confirm that the prefilled EXIF data is good, or remove location data.

Primarily for Wikipedians, but also has lots of other formats (which is nice, but makes the page awfully complicated). We don't care about Dublin Core, we don't even care about Wikipedia's Coord template. We just want something for Wikimedia Commons.

Still on another page, not integrated with Commons upload or File: pages.

Usability is poor -- again , way too many options for almost all photos, impossible for a naive user to guess what's going on

Bad - you need to control-click to set the point. Otherwise 0,0 is preselected. We want a tool that can also record "no geocode for this photo".

Good point - does headings, radius, etc, although this functionality achieved with special Alt-click, shift-click, etc. Not obvious or intuitive

Good - you can drag the marker around, which is intuitive, although I think clicking is still more likely to be guessed at.

In the spirit of NORULES, feel free to abandon any aspect of this specification that does not make sense, or seems like it will take a very long time to implement. It just has to satisfy the broad goals listed above.

That said, it is expected that the following behaviour should be pretty easy to achieve with modern mapping libraries and jQuery.

It may be difficult to achieve all the behaviour in a cross-library manner, where it works on OpenLayers as well as Google Maps, for instance. Small differences can be ignored.

The names of methods and parameters are just suggestions. If they need to be changed to conform to existing conventions, please do so.

Although the mockups are crude, it is expected that all the buttons and so on are generated with jQuery.UI, and thus are themed by default. When colors have to be chosen (like the greys or light blue in the mockups) please use the palette of Vector colors. If there's a conflict between what I sketched and the Vector guidelines, Vector should win if at all possible.

The following code would create a map widget on the page, pre-centered and pre-zoomed to a point in San Francisco, CA.

// at present, these are the only defined options, but add more if they make sense to control the map display
var options = {
latitude: 37.775,
longitude: -122.4183
};
// create widget on page, at HTML element located at #foo
var locator = $('#foo').locator( options );

If either of the latitude and longitude options are insane, the map should behave as if neither were present.

Rough mockup of how location widget appears when editing location, zoomed out far

We begin zoomed out very far. The map widget will show a standard "slippy" map with minimal controls.

A user can pan the map around by grabbing the map and dragging it in any direction. They can zoom in or out. The programmer can choose whether to allow changing to different modes (such as between satellite or street maps). Photographic views like Google Street View or Bing's bird's eye view are left as a choice to the programmer.

A text field appears below the map. This is used to find locations with geocodable strings, such as addresses, landmark names, and so on. The geocoding API will of course vary depending on the maps provider used. If there are any providers for whom this service is not available then the field should not be shown.

The field will have grey "hint" text such as shown in the mockup. This text disappears if the text field contains any content or has the mouse focus. The help text reappears if text field does not have focus and contains only the empty string or whitespace.

If the user enters a location in that field and presses return, a call to a geocoding service will be made, to obtain coordinates.

If the location is found:

If one location is found, this will drop a marker onto the map, and also store this as the widget's current location.

If a number of locations are found, this should be made visible with noticeably different markers (both in color and icon). Clicking on one of these icons should cause that to become the selected marker (or, erase all such search markers and drop a new one where that was, same thing).

See Multichil's tool (linked above) for ideas about how to display multiple search results... uncertain about how this should be done, please experiment. Just make it easy to "convert" one of the found points into our marker point, ideally with a single click.

The text field will be blanked if the user subsequently changes the marker location by clicking elsewhere on the map.

If the location is not found, an error message is shown in red near the text field (probably below it, or perhaps right on the map itself with appropriately opaque background). The error message will be somethng like "That location could not be found." The unfindable location remains visible in the text box. If the user makes any change to the text in that box, the error message disappears.

Rough mockup of how location widget appears when not editing, and having data. Usual initial state prefilled with EXIF, or after interactive editing of location

Here we see the widget in its "closed" state while storing a location. The map shown is not interactive; clicking anywhere on it just opens up the widget again, which will show an interactive map with the location marker pre-set, similar to how it appeared in the "Open", location set state.

The user does not take any special action to show wikitext. Instead, this will be handled by other scripts on the page (which initialized the map widget in the first place). The widget will define a getWikiText method, such that this sample scenario works.