OpenStreetMap

Remote control for iD

Posted by Anton Khorev on 24 April 2022 in English.

As you remember from my last diary entry, I tried to make note-viewer communicate with editors. It was relatively easy to do with JOSM because JOSM supports remote control. If I want to open a bunch of notes in JOSM, I can make a remote control call for each note to open its url which JOSM understands. But with iD I had to concede a defeat. The easiest way to open selected notes in iD seems to be exporting the notes to a GPX file and opening it as a custom data layer.

map parameter

But since then you may have noticed that iD has appeared in note-viewer’s toolbar. That means I had a rematch with iD and although I didn’t win it either I got at least something. That something is opening a given map location in iD without losing the edits. That doesn’t seems like much and last time we could open iD at the coordinates we wanted. The difference is that now we can tell the already running iD instance to go there. If we look at the location bar while panning the map in iD we’ll see that map in the hash part is being updated with current coordinates. That’s not surprising, map is one of the documented parameters, we can open iD with map set to the place we need and iD will zoom there. But can we update the location ourselves while iD is running? We may try to edit it right in the location bar. For example, the first number of map value is zoom. Let’s change it and press enter. Nothing seems to happen…

Is it possible for a web application to react to such location updates? Yes. For example, note-viewer also updates the location depending on values entered into forms. That allows to link its user notes queries with OSM Smart Menu. The username goes to the display_name parameter. It’s also possible to edit the location manually, replacing the username with another one. If we do this, note-viewer updates the notes. How does note-viewer know that we edited the location? By listening to the hashchange event. If iD also listened to this event, it could update the view in response to map changes. We’ll look at the source code and we’ll find that it does actually listen to this event. And it updates the view. Yet it doesn’t work.

We’ll make it work. Actually it’s easy. Remember my note in the last diary entry that we assume iD to be the selected editor in user’s settings. That’s because /edit urls on the osm website are not iD’s own urls. They open the preferred editor that can also be the one listening to remote control. But even if the preferences are set to iD, the page at /edit is not plain iD. It contains an osm site header after which iD is embedded. And we can see that it’s embedded with a url ending with /id before any hash parameters. That’s the url we need to open. We won’t get the site header but we will get iD listening to location updates.

Now we can have some remote control for iD. We’re not going to alter the location manually of course. We’ll have note-viewer do it for us. First we can replicate the Load map area button that works with JOSM. If we have JOSM running we may want to tell it to load the data at some place. That place might be related to our notes and we may have it in the note-viewer’s map view. We can press the Load map area button in note-viewer and JOSM will load that area. Other data including our unsaved edits are not going to be lost. What is the similar thing for iD? It doesn’t have the load area functionality and it doesn’t need to. Instead it just loads whatever in its view if the zoom is high enough. So we just need to zoom to the place of interest. We already know how to do it. I mean, note-viewer knows, and that’s what the iD: Load map center button is for. What it does is opening a named window with the map parameter set to note-viewer’s map zoom/lat/lon. When pressed for the first time it opens a new window with iD. All the subsequent presses change the location of that window by updating map. iD reacts by zooming to new coordinates and loading the data around the place.

gpx parameter

Another thing note-viewer does through remote control is loading selected notes. We already know that getting it to work by setting the url parameters is not easy. First of all, there are no parameters related to notes. Instead we can try to represent notes by gpx waypoints. There is a parameter for that but in order to convince iD to load our gpx data it must come from an acceptable source. Basically we can’t generate the data in note-viewer and feed it directly to iD, that’s why we had to go through save-file-load-file route which can’t be automated. And it can’t be automated on purpose, because security. What if some evil script passes some data taking advantage of some exploit? That evil script as well as note-viewer will need to convince the user to save and load the data file.

But even if we can’t make iD to load several note waypoints at once, we can still make it with one note. We can get gpx data for a single note from the osm api, which is an acceptable source for iD. Therefore we can alter the gpx parameter to point to that data like we do with map, right? Actually no, we can’t alter gpx this way. We can launch iD with gpx set to an osm api url and it will load. However we can’t alter gpx for an already running iD instance. Well, we can, but iD won’t react to it. If we look again at the hashchange listener, we’ll see that there’s no code to handle gpx updates. So no such remote control for us.

Discussion

Log in to leave a comment