MarcusWolschon / osmeditor4android

Vespucci is a OpenStreetMap editor for Android
http://vespucci.io
Other
371 stars 83 forks source link

Mapillary API v3 EOL #1337

Closed simonpoole closed 3 years ago

simonpoole commented 3 years ago

Mapillary is sunsetting its current API at, imho, very very short notice:

Mapillary will migrate from our current API to a new version in the first half of 2021. The current version, API v3, includes the following public endpoints from the https://a.mapillary.com domain:

v3/images

v3/sequences

v3/object_detections (formerly v3/image_detections)

v3/map_features

v3/users

v3/me/uploads

v3/changesets

v3/leaderboard

Your apps may depend on multiple APIs from this list, and you will need to migrate to the new version, API v4, for your apps to continue working with Mapillary. Some features may be more limited in functionality, require different methods of use, or be retired altogether. We plan to make these changes transparent to you as a key user as soon as possible.

Please be aware of the following timeline:

March 2021: No new client IDs may be created for API v3

March 2021: Mock API with limited images available for testing and development

May 2021: New images uploaded to Mapillary will not be accessible via the v3 API

May 2021: API v3 will be retired and replaced entirely by API v4

The precise launch date for API v4 is yet to be determined, but will be prior to the shutdown of API v3 in May 2021. If you are interested in beta testing the API, please reach out to support@mapillary.com with a description of your current utilization of the Mapillary API to learn more about testing opportunities.

It seems that Facebook is expecting us to reserve April and May for implementing the changes and creating a new (at least) minor release specific for them.

@cbeddow any more information forthcoming soon that would make planning easier?

cbeddow commented 3 years ago

Hi Simon,

Please let me know if you have an idea of what information would help make it as easy as possible for you and other developers. I want to get developers involved in feedback on the initial specification which I can share tomorrow as a PDF, and anyone interested in being a beta tester should have access to a mock API in March.

I think after my sending along the spec you may be able to come up with specific questions that we can then dive into. I want to get anyone interested to be involved as a tester as early as possible and use the feedback to adjust where we can, or otherwise plan for future iterations.

Best,

Chris

Get Outlook for Androidhttps://aka.ms/ghei36


From: Simon Poole notifications@github.com Sent: Wednesday, February 10, 2021 1:22:50 PM To: MarcusWolschon/osmeditor4android osmeditor4android@noreply.github.com Cc: Christopher Beddow cbed@fb.com; Mention mention@noreply.github.com Subject: [MarcusWolschon/osmeditor4android] Mapillary API v3 EOL (#1337)

Mapillary is sunsetting its current API at, imho, very very short notice:

Mapillary will migrate from our current API to a new version in the first half of 2021. The current version, API v3, includes the following public endpoints from the https://a.mapillary.com domainhttps://a.mapillary.com domain:

v3/images

v3/sequences

v3/object_detections (formerly v3/image_detections)

v3/map_features

v3/users

v3/me/uploads

v3/changesets

v3/leaderboard

Your apps may depend on multiple APIs from this list, and you will need to migrate to the new version, API v4, for your apps to continue working with Mapillary. Some features may be more limited in functionality, require different methods of use, or be retired altogether. We plan to make these changes transparent to you as a key user as soon as possible.

Please be aware of the following timeline:

March 2021: No new client IDs may be created for API v3

March 2021: Mock API with limited images available for testing and development

May 2021: New images uploaded to Mapillary will not be accessible via the v3 API

May 2021: API v3 will be retired and replaced entirely by API v4

The precise launch date for API v4 is yet to be determined, but will be prior to the shutdown of API v3 in May 2021. If you are interested in beta testing the API, please reach out to support@mapillary.commailto:support@mapillary.com with a description of your current utilization of the Mapillary API to learn more about testing opportunities.

It seems that Facebook is expecting us to reserve April and May for implementing the changes and creating a new (at least) minor release specific for them.

@cbeddowhttps://github.com/cbeddow any more information forthcoming soon that would make planning easier?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/MarcusWolschon/osmeditor4android/issues/1337, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACQQ4KQMIBGZQLVB7JEAAWLS6LTJVANCNFSM4XMYRCWA.

cbeddow commented 3 years ago

This specification for the API is a first draft, and I would really appreciate if you can read through and provide feedback on any concerns, or let me know questions. This will help me both clarify a future version of this, as well as determine if we should or can make any changes to the plan to be better accommodating within our limits.

Mapillary v4 API.pdf

simonpoole commented 3 years ago

Thanks for the spec, I'll give it a look asap (on vacation for another week).

My main concern is less the changes per se (I'm assuming that we use fairly basic functionality that will still be available in some form), but that essentially there's only one month, if even that, of parallel operation planned.

To put that in to perspective we typically have a beta period of about two months for minor releases, and more like three for major ones.

Given the typical delay between release and the app actually being available on the playstore ~2 weeks (this is due to specifics of how we are organized), I would have to release mid-May to be half sure of seemless transition.

davidpnewton commented 3 years ago

"Please let me know if you have an idea of what information would help make it as easy as possible for you and other developers."

How about information on Facebook backing down from this and providing an actual reasonable period of notice for the change?

How about actually finalising the new API spec and getting it up and running properly before even contemplating retiring the old API?

The timeframes are ridiculously tight. There is no proper deployment of the new API before the old API is retired. The new API spec is not even finalised yet. All-in-all a textbook case of botched, rushed switching which is utterly unjustified in its compressed timespan.

cbeddow commented 3 years ago

@davidpnewton @simonpoole Maybe the communication was unclear: for testing the build there should be up to 3 months of overlap (All of March, April, and May), with a mock API for testing available in March and the old API functioning through end of May. The key difference is that we will cutoff creating client IDs for API v3 in March so that we don't have new apps that need to be migrated. Exact dates aren't promised until we can do so.

@davidpnewton thanks for the input. I don't think it's fair to call it botched, and though I'd agree that a longer timespan is always ideal, I'm working to help others as best as possible with the constraints given. The infrastructure supporting API v3 has a hard shutdown date around the end of May and there's no way around it.

simonpoole commented 3 years ago

As a more general comment. Mapillary is run by grownups and they need to make their own decisions and live with the consequences.

What is clear is that even in an ideal outcome, aka all apps are migrated by the end of May, end users will not migrate anywhere so fast to fixed versions, so a lot of friction is to be expected in the following months.

davidpnewton commented 3 years ago

So why did I refer to it as botched? Two primary reasons:

  1. The incredibly compressed timescale, particularly when dealing with developers who are not full-time in many cases;
  2. Not even having a finalised version 4 in place before announcing the end of version 3.

An absolute pre-requisite before even thinking of starting the deprecation process must be a finalised spec for the next version of the API. If there's no finalised spec of the next version of the API then how are app developers even supposed to start developing against it properly? Once there's a finalised spec then it is reasonable to stop issuing version 3 keys. Once there's a finalised spec then it is reasonable to give notice that concurrent running will stop at some point in the future.

What might be a more reasonable timetable? Publish the draft version now for comments up to the end of March. Publish a final version at the end of March. Also make it clear that once the final version is published soon thereafter new keys for the old version of the API will stop being published. Say give a month's notice, and so stop issuing new keys at the end of April. Also at the point the final API spec is published give six months' notice of the cessation of concurrent support for version 3 and version 4. So full transition is complete at the end of September 2021.

That gives app developers enough time to implement and test the new API in their programs. It also gives them time to do it against a completed spec. Now if the underlying infrastructure for version 3 is going away in May then that is indeed a hard deadline. However all that means is that the transition process should have begun several months ago, well before Christmas.

cbeddow commented 3 years ago

I'll pass on an updated spec as soon as available, and if you'd like to get on a call and go over it once more materials are available, then let's do that. I'll pass on an updated spec as soon as available, and if you'd like to get on a call and go over it once more materials are available, then let's do that.

The spec is incomplete because I want to give as much advanced notice as possible and have user input on the spec before it's finalized, in case that influences some decisions. The team and I do not want to design a spec that has zero end user feedback before finalization.

I do see reason in your timeline input @davidpnewton:

  1. Publish the draft version now for comments up to the end of March. <- This is already compatible with our time, comments welcome in real time and crucial to building this for the end user

  2. Publish a final version at the end of March. <- This aligns with our goals but can't be absolute certain as of today.

  3. Also make it clear that once the final version is published soon thereafter new keys for the old version of the API will stop being published. Say give a month's notice, and so stop issuing new keys at the end of April. <- we plan to stop new keys before publication to reduce the need for migration and creation of new dependencies on v3. I'll bring your suggestion forward.

  4. Also at the point the final API spec is published give six months' notice of the cessation of concurrent support for version 3 and version 4. So full transition is complete at the end of September 2021. <- This is fundamentally incompatible with our timeline. Even if 6 months is much better, which I won't debate, the nature of Mapillary changing infrastructure (due to acquisition prompting a more sudden change in infrastructure than typical long term, 1+ year out planning would produce) requires a hard date to shut down the infrastructure that API v3 is reliant upon. No way around this.

As a last note, I will take a look through your repository and see what exact places I recommend the changes occur, or welcome any point in the right direction from you. My job is to help make implementation go smoothly so I'll do my best within the limitations and hopefully make it simpler for you.

cbeddow commented 3 years ago

Hi all, I've taken a look with our Android engineer. So we see Mapillary in these key functions:

  1. Getting Mapillary sequences in a certain area: URL url = new URL(mapillaryApiUrl + "sequences?client_id=" + apiKey + "&bbox=" + box.getLeft() / 1E7d + "," + box.getBottom() / 1E7d + "," + box.getRight() / 1E7d + "," + box.getTop() / 1E7d);
  2. And `https://images.mapillary.com/ to get images.

These are the two changes for you, which I'll help with once we have the mock/sandbox API for testing:

  1. Because bbox query on server won't be possible, we can borrow code from JOSM/Mapillary JOSM plugin in Java that may help, which will take a bbox and convert it to a z/x/y tile(s), and retrieve the data that way. Is your app compatible with displaying a vector tile directly instead, or is it most efficient for you to retrive the data as geojson for display?
  2. The image JPEG URL endpoint will change, and may be dynamic (I believe for security purposes but I am following up on why and how). In a nutshell, for each image key, you'll make an API request to Mapillary and receive its current JPEG URL, then can display it. This URL may also be stored in the image (point data) vector tile already so could skip the API call.

I will follow up with more detail, ideally on exactly what endpoints and functions you will need to replace the above two.

simonpoole commented 3 years ago

Hi @cbeddow I did give the draft doc a look yesterday, and yes, the main issue is going to be the MVT support which we currently don't have.

It isn't a major thing as such, just a small issue of programming (determining which tiles to retrieve etc is naturally something we do for raster layers) but will need data structures for caching and so on, and then decoding the tiles themselves. We do support various PBF based data formats so again there is no fundamental hurdle.

cbeddow commented 3 years ago

Great, I am coordinating with the dev working on JOSM and will share anything he thinks may be helpful in these cases, since it's Java, so that may help.

simonpoole commented 3 years ago

Great, I am coordinating with the dev working on JOSM and will share anything he thinks may be helpful in these cases, since it's Java, so that may help.

In general JOSM code (maybe not for this plugin) is off limits because GPL.

cbeddow commented 3 years ago

Good to know. I will see if this specific code (since our team will develop some of it and push into the Mapillary plugin for JOSM, or to JOSM directly) may be exempt. If not, will confirm too!

cbeddow commented 3 years ago

Hi all,

Here are two identical examples of the mock API (Python notebook and Markdown):

https://mapillary.github.io/mapillary_solutions/mock_api_v4/mapillary_mock_api_v4.md https://mapillary.github.io/mapillary_solutions/mock_api_v4/mapillary_mock_api_v4.ipynb

Please let me know how it looks on an initial pass. I can get on a call to take a deeper look if that helps. I'm curious if you see any problems with Java that the Python example wouldn't reveal. It sounds like tiling will be a specific challenge. Anything else you see?

I need to add a few more examples that we've expanded as of today:

  1. closeTo search: find nearest image key to input lon,lat
  2. bounding box search: get list of images withing lon1,lat1,lon2,lat2 bbox

The Python examples have some use of 3rd party libraries which we're hoping to reduce where possible, despite a light set of functions server side like closeTo and bbox search.

simonpoole commented 3 years ago

@cbeddow are the tile urls in the examples suppose to work ?

For example

https://a.mapillary.com/v3/graph/tiles/17/68594/45883.mvt?client_id=...

Returns an error for me (to be clear I've tried a range of zoom levels).

cbeddow commented 3 years ago

@simonpoole ah that's my my fault, we had changed which are available. Please use 14/8784/5133. I'll update the doc.

I'll share new examples of closeto and bounding box when we have a sample up to date.

Is there anything you find particularly disagreeable right now that I can help look into also?

simonpoole commented 3 years ago

@simonpoole ah that's my my fault, we had changed which are available. Please use 14/8784/5133. I'll update the doc.

Actually it is probably my fault as I assumed that there would be tiles for the whole globe.

simonpoole commented 3 years ago

https://a.mapillary.com/v3/graph/tiles/sequences/14/8784/5133.mvt?client_id=.... currently times out (assuming this is really what the API expects the URL to look like plus a valid api key naturally).

cbeddow commented 3 years ago

@simonpoole yes this is the correct format, just ongoing changes might be making it unresponsive at the moment. I'm working on seeing what we can do to get a larger interactive test area that makes visualization easier. I'll likely be setting up fake data for a single small town for example, including image and sequence locations.

simonpoole commented 3 years ago

@cbeddow it would be helpful if we could get a sample tile of every planned type till the API is actually working.

For testing purposes I started using what it seems you provide for the mobile app courtesy of a Kaart employee, it seems as that API returns an illegal MVT of 24 byte size to indicate that it doesn't have data at a specific layer. This is sub optimal as proper handling would require decoding immediately on download (right now I hack around the issue but that isn't something I would want to do for production). I would suggest returning a proper HTTP error code or, not ideal either, using the convention that tegola uses, that is returning empty contents.

tsmock commented 3 years ago

https://tiles3.mapillary.com/v0.1/14/3262/6261.mvt Gives me: [0x1A, 0x16, 0x78, 0x01, 0x0A, 0x0F, 0x6D, 0x61, 0x70, 0x69, 0x6C, 0x6C, 0x61, 0x72, 0x79, 0x2D, 0x65, 0x6D, 0x70, 0x74, 0x79, 0x28, 0x80, 0x20] (24 bytes, I presume this is the bytes of the illegal MVT tile you are referring to)

This becomes:

0x1A => 0001 1010 => value = 3 (layer), wiretype = 2 (length delimited)
0x16 => 0001 0110 => length = 22
  0x78 => 0111 1000 => value = 15 (version), wiretype = 0 (varint)
    0x01 => version = 1
  0x0A => 0000 1010 => value=1 (name), wiretype = 2 (length delimited)
  0x0F => 0000 1111 => length=15
  name = [0x6D, 0x61, 0x70, 0x69, 0x6C, 0x6C, 0x61, 0x72, 0x79, 0x2D, 0x65, 0x6D, 0x70, 0x74, 0x79 ]
            = [m, a, p, i, l, l, a, r, y, -, e, m, p, t, y] => mapillary-empty
  0x28 => 0010 1000 => value = 5 (extent), wiretype = 0 (varint)
  0x80 => 1000 0000, leading 1, needs next byte
  0x20 => 0010 0000
  0x20 + 0x80 => 0010 0000 000 0000 (the 000 is deliberate, drop leading 1)
                        => 1 0000 0000 0000
  extent=4096 (extent is uint)

version=1 name=mapillary-empty extent=4096 features = [] (default) keys = [] (default) values = [] (default)

So, it is (technically) a valid MVT file. Are you looking for a layer that doesn't exist? I.e., getLayer("mapillary-sequences") throws NoSuchElementException.

simonpoole commented 3 years ago

A valid MVT needs to contain at least one feature according to the spec.

But that's not the point: one way or the other I have to determine if tiles for a certain zoom level are present or not, at the same time avoiding requesting non existent tiles time and time again.

tsmock commented 3 years ago

A valid MVT needs to contain at least one feature according to the spec.

Just in case, are we reading the same spec? https://github.com/mapbox/vector-tile-spec/tree/master/2.1 (what I was primarily looking at during implementation) https://github.com/mapbox/vector-tile-spec/tree/master/1.0.0 (what the vector tiles are saying should be the specification)

One of the major differences is A Vector Tile SHOULD contain at least one layer. A layer SHOULD contain at least one feature. (v2) versus A vector tile can consist of one or more named layers and containing one or more features. (v1). This is directly applicable here (version=1).

I've primarily focused on implementing the v2 spec, since it was largely billed as a clarification of the v1 spec. I guess I assumed that the v1 language was essentially the same as the v2 language, with the v2 language being more precise, which is what it looked like to me.

But as far as

But that's not the point: one way or the other I have to determine if tiles for a certain zoom level are present or not, at the same time avoiding requesting non existent tiles time and time again.

goes, how are you ordinarily caching the tiles? Can't you just reuse the same code?

cbeddow commented 3 years ago

I'm sharing this with our backend engineer to check what other perspective I can offer, otherwise Taylor has been testing this too and may know the current limits better than me.

@simonpoole are you look for just images and sequences, or anything else like traffic signs?

simonpoole commented 3 years ago

But that's not the point: one way or the other I have to determine if tiles for a certain zoom level are present or not, at the same time avoiding requesting non existent tiles time and time again.

goes, how are you ordinarily caching the tiles? Can't you just reuse the same code?

Well that is what I'm doing.

But even with raster tiles you need a reliable and efficient way to determine if a tile exists or not (typical case are mosaics with regionally different max zoom levels), this is even more important with vector tiles as zoom levels will be missing from the tile pyramid as a rule.

The problem with the mapillary approach is that it provides a superficially valid tile that could in principle be rendered as nothing (and therefore replacing data rendered from a lower zoom tile), so you need to know that this is an indicator that the zoom level does not exist. Which one way or the other requires a mapillary specific hack with the current "empty" tile.

simonpoole commented 3 years ago

@simonpoole are you look for just images and sequences, or anything else like traffic signs?

Currently just images and sequences, not ruling out adding more down the road, but the goal is to get equivalent functionality back for now, not expand it.

tsmock commented 3 years ago

But even with raster tiles you need a reliable and efficient way to determine if a tile exists or not (typical case are mosaics with regionally different max zoom levels), this is even more important with vector tiles as zoom levels will be missing from the tile pyramid as a rule.

The problem with the mapillary approach is that it provides a superficially valid tile that could in principle be rendered as nothing (and therefore replacing data rendered from a lower zoom tile), so you need to know that this is an indicator that the zoom level does not exist. Which one way or the other requires a mapillary specific hack with the current "empty" tile.

I've been assuming that when the mapillary-empty tile indicates there is no data in the area, even if you go in closer (I haven't checked that, especially around the edges). I haven't coded that assumption in, but I also haven't coded around the opposite assumption (higher zoom levels may contain data where mapillary-empty tiles exist, and should be prioritized over the mapillary-empty tile).

Do you have a test area where the assumption is wrong?

tsmock commented 3 years ago

@simonpoole : As an FYI, the vector tile feature ids (for images, specifically) are not unique in the tiles I've been using for testing. I'm hoping that they will be in the v4 API (I'm fairly confident that they will be using MVT v2 in the v4 API, which specifies that ids SHOULD be unique, unlike v1 which doesn't specify anything).

A feature MAY contain an id field. If a feature has an id field, the value of the id SHOULD be unique among the features of the parent layer.

simonpoole commented 3 years ago

Sigh

https://twitter.com/mapillary/status/1386732349321318404?s=19

cbeddow commented 3 years ago

@simonpoole let me know if you want to catch up on a call so I can get a better understanding here and package the feedback to our backend engineer. What I'm wondering is if you're thinking it would be useful to simply have an API call that passes a tile ID and except a true/false response, asking "does this tile exist"--is that what you'd have in mind for server side, and would prevent breaks?

re the MapWithAI thing above--that's because iD editor doesn't support vector tiles at all and was calling the API in bboxes and doing caching on its own. The code hasn't been merged to iD yet but is pending, but works in MapWithAI fork. Not based on the new vector tile that you're looking at either, just the old one, but in anticipation of the new one.

simonpoole commented 3 years ago

@cbeddow essentially sample tiles/running example of the new API. There is really just so much that can be done without the actualy "thing" that we are supposed to support.

cbeddow commented 3 years ago

Getting this to you as soon as possible, full tiles under being internally tested and reviewed currently!

simonpoole commented 3 years ago

/me drums on table

davidpnewton commented 3 years ago

Marvelous definition of "as soon as possible" they've got isn't it.

cbeddow commented 3 years ago

Yes, marvelous indeed! offer still stands to have a call and go over these things.

New API resources: https://www.mapillary.com/developer/api-documentation/

Current priority for me since Thursday's launch is handling directly reported user bugs so apologies that I haven't jumped right on providing resources here.

I'm working on a tutorial blog post for aspects of the new API, including 1) basic requests and 2) using tiles and 3) authentication/upload.

Tile coverage endpoint is here: https://tiles.mapillary.com/maps/vtp/mly1_public/2/{z}/{x}/{y}

Get a new access token (formerly client ID) here for API (not needed for tiles): https://mapillary.com/developer

Here's a quick demo in Mapbox JS GL for the tiles, works same as always with new endpoint: https://codepen.io/cbed/pen/NWpeEqw

What else can I provide for you?

simonpoole commented 3 years ago

What else can I provide for you?

Nothing right now, initial rough support is running right now, will need some more work before it is release ready.

I would point out that the API documentation needs more examples or formal definition of what the calls return (for example retrieving image ids for a specific sequence).

simonpoole commented 3 years ago

@cbeddow it would be really helpful if

Sequence Represents a sequence of Image IDs ordered by capture time Endpoints https://graph.mapillary.com/image_ids?sequence_id=XXX Fields id - ID of the image belonging to the sequence

would support returning geometry or computed_geometry. As the fields returned by the call need to be selected in any case, there is no real downside to this IMHO.

Not having the geometry available makes it difficult to center the screen on the current image, and the workarounds are all ugly:

simonpoole commented 3 years ago

Just for the record it is not just me that has the issue, I just have more qualms about hacking around obvious deficiencies in the API than others (which would have been avoidable if we could have actually had access to a test instance of the API).

See https://matrix.to/#/!LzhExwiqAnBnpnsLJk:matrix.org/$16246261481408092ajNMk:matrix.org?via=matrix.org&via=nordgedanken.dev&via=alsd.eu

cbeddow commented 3 years ago

@simonpoole can you tell me more about the flow you are working on?

1) you have the sequence ID 2) you want to get the linestring geometry of the sequence 3) you want to then select an image key from that sequence and center the screen on its lon,lat

Is that right? And you are getting the sequence based off a user querying the vector tile?

Would it not make sense to get the image key from the list of images in the sequence, then call graph.mapillary.com/IMAGEID?fields=id,geometry, is that in line ith what you want to do?

If not, please let me know if you can correct me, I'll describe this better in filing a feature request. In general I fully agree that it seems logical to just allow adding geometry as a field in that API request to quickly plot the image on the map without doing a second request.

simonpoole commented 3 years ago

@cbeddow the actual flow in question is

Main processs                                       Image viewer

User clicks on map

Selected image is retrieved from tile

Sequence retrieved via API

Image marker highlighted

Request viewer to display image id       ->         Receive request to display image`

                                                    Load image async (downloading it if necessary)

                                                    User hits next or previous image button

Receive request to highlight image       <-         Request main process to highlight next image

Highlight image and center*                         Load next image async 
  * is where we need the coordinates

This is naturally a fairly complicated flow, but you run in to the same issues if you simply wanted to follow and highlight the image markers belonging to the same sequence in isolation.

The geometry of the sequence contains the coordinate information as long as you remain in the same tile and this is what the JOSM plugin uses, but it requires ugly hacks to cross tile boundaries, and I would go as far and say there are multiple scenarios where this could fail.

Note that even if we would fall back to using the sequence geometry, we still need to retrieve the list of image ids in the sequence so that we can determine the ordering (aka at which position which image is in the sequence), so nothing is saved at all.

tsmock commented 3 years ago

I know this is slightly off-topic (I don't think you've gotten to the point where you are handling detection drawing yet, anyway), but where the API docs say "geometry - string, base64 encoded polygon" under "Detection" fields, it means "base64 encoded vector tile geometry". Or at least that is what it looks like to me.

$ echo -n 'GjgKBm1weS1vchIYEgIAABgDIhAJkCawDRq4BgAAhAO3BgAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==' | base64 --decode | hexdump
0000000 1a 38 0a 06 6d 70 79 2d 6f 72 12 18 12 02 00 00
0000010 18 03 22 10 09 90 26 b0 0d 1a b8 06 00 00 84 03
0000020 b7 06 00 0f 1a 04 74 79 70 65 22 09 0a 07 70 6f
0000030 6c 79 67 6f 6e 28 80 20 78 01
0x1a 0x38 -> field 3, length 56 (MVT "layer")
  0x0a 0x06 -> field 1, length 6 (MVT layer "name")
    [6d, 70, 79, 2d, 6f, 72] -> "mpy-or"
  0x12 0x18 -> field 2, length 24 (MVT layer "features")
    0x12 0x02 -> field 2, length 2 (MVT feature "tags")
      [0x00 0x00]
    0x18 -> field 3 (MVT feature "geometry type"), 0x03 -> "polygon"
    0x22 0x10 -> field 4, length 16 (MVT feature "geometry", coordinates are zig-zag encoded)
      [09 90 26 b0 0d 1a b8 06 00 00 84 03 b7 06 00 0f]
      0x09 [[0x90, 0x26], [0xb0, 0x0d]] -> MoveTo (2440, 856)
      0x1a -> LineTo x3
        [[0xb8, 0x06], [0x00]] -> LineTo(412, 0)
        [[0x00], [0x84, 0x03]] -> LineTo(0, 194)
        [[0xb7, 0x06], [0x00]] -> LineTo(-412, 0)
      0x0f -> ClosePath
  0x1a 0x04-> field 3 length 4 (MVT layer "keys")
    [0x74 0x79 0x70 0x65] -> [type]
  0x22 0x09-> field 4 length 9 (MVT layer "values")
    0x0a 0x07 -> string, length 7
      [0x70 0x6f 0x6c 0x79 0x67 0x6f 0x6e] -> [polygon]
  0x28 0x80 0x20 -> field 5 (MVT layer "extent") = 4096
  0x78 0x01 -> field 15 (MVT layer "version") = 1

so

{
    "layer": {
        "name": "mpy-or",
        "features": [
            {
                "tags": [[0, 0]],
                "type": "polygon",
                "geometry": [
                    [2440, 856],
                    [2852, 856],
                    [2852, 1050],
                    [2440, 1050]
                ]
            }
        ],
        "keys": ["type"],
        "values": ["polygon"],
        "extent": 4096,
        "version": 1
    }
}

I haven't gotten around to actually drawing the geometry yet, but my guess is that the geometry is based off of the "original" pixels (i.e., https://graph.mapillary.com/:image_id?fields=width,height).

I'm not certain why Mapillary is adding the tag type=polygon when MVT Feature field 3 essentially says the same thing.

EDIT: That detection comes from https://www.mapillary.com/app/?pKey=135511895288847&focus=photo (turn on All traffic signs/All points under map data). This specific detection is for a street sign labeled "Rood Av".

simonpoole commented 3 years ago

Initial support merged https://github.com/MarcusWolschon/osmeditor4android/pull/1430