Skip to content

Feature/panoramax#236

Open
ofr1tz wants to merge 30 commits intodevelopfrom
feature/panoramax
Open

Feature/panoramax#236
ofr1tz wants to merge 30 commits intodevelopfrom
feature/panoramax

Conversation

@ofr1tz
Copy link
Copy Markdown

@ofr1tz ofr1tz commented Feb 23, 2026

Depends on

Changes

This enables the MapSwipe backend to handle View Streets projects with different image providers (currently Mapillary and Panoramax).

  • Adds image provider to the View Streets project specifics
  • Adds logic to download and process Panoramax metadata
  • Maps Panoramax metadata attribute names on the respective Mapillary attribute names for filtering
  • Changes max length of task ID to accommodate Panoramax image IDs as task IDs

This PR doesn't introduce any:

  • temporary files, auto-generated files or secret keys
  • n+1 queries
  • flake8 issues
  • print
  • typos
  • unwanted comments

This PR contains valid:

  • tests
  • permission checks (tests here too)
  • translations

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 24, 2026

Codecov Report

❌ Patch coverage is 87.89809% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.46%. Comparing base (6c9dd95) to head (3089d82).
⚠️ Report is 4 commits behind head on develop.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
utils/geo/street_image_provider/models.py 68.75% 6 Missing and 4 partials ⚠️
project_types/street/api_calls.py 87.09% 2 Missing and 2 partials ⚠️
project_types/street/project.py 80.00% 2 Missing and 2 partials ⚠️
...ps/project/tests/e2e_create_street_project_test.py 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #236      +/-   ##
===========================================
+ Coverage    87.41%   87.46%   +0.04%     
===========================================
  Files          205      206       +1     
  Lines        12458    12579     +121     
  Branches      1049     1067      +18     
===========================================
+ Hits         10890    11002     +112     
- Misses        1181     1186       +5     
- Partials       387      391       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ofr1tz ofr1tz marked this pull request as ready for review February 24, 2026 17:42
@frozenhelium frozenhelium requested a review from susilnem March 6, 2026 08:09
return firebase_models.FbMappingTaskStreetCreateOnlyInput(
# XXX: converting this to int for backwards compatibility
taskId=int(task.firebase_id),
taskId=task.firebase_id,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to remove the casting of firebase_id?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we use the street-level image ID as the MapSwipe task ID so that we can easily link MapSwipe results back to the original images without having to add an additional task attribute.

However, whereas Mapillary has integer image identifiers, Panoramax uses UUID v4 for identifiers.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still cast it to int for backward compatibility if the provider is Mapillary

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be in street/project.py?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is consistent with raster_tile_server and vector_tile_server also in utils/geo/


# Type hints
id: int
id: int | str
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason on changing the type?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: task id == Panoramax image ID (UUID v4)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a type hint.
How was "id" change to "str" in the database.

Also, why change the internal "id" representation?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. This was a mix-up with the firebase ID, the internal id representation does not need to be changed indeed.

@ofr1tz ofr1tz force-pushed the feature/panoramax branch from 71352ae to f15f817 Compare March 19, 2026 15:50
@ofr1tz ofr1tz requested a review from susilnem March 23, 2026 16:06
@ofr1tz ofr1tz force-pushed the feature/panoramax branch 2 times, most recently from a2dad0a to f15f817 Compare March 23, 2026 16:53

# Type hints
id: int
id: int | str
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a type hint.
How was "id" change to "str" in the database.

Also, why change the internal "id" representation?

Comment on lines +196 to +197
else:
raise Exception(f"Unknown provider {getattr(provider.name, 'value', '')}")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use assert_never so that we get static type checks.

endTime: String
isPano: Boolean
organizationId: String
panoOnly: Boolean
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might require a migration.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my understanding:

  • A migration is not required as the attribute is stored in JSON fields, not in a dedicated column
  • We probably do not need a backfill neither, as this would only be a potential issue for unpublished project drafts created with the former version having isPano: true. The filter is only used during project processing.

"""Numeric value as string"""
aoiGeometry: String!
customOptions: [CustomOptionInput!] = null
imageProvider: StreetImageProviderInput = null
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might require a migration.

Copy link
Copy Markdown
Author

@ofr1tz ofr1tz Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nested key inside the JSON field project_type_specifics and does not create a new column.

Backend treats it as optional and defaults to MAPILLARY, so existing records without imageProvider continue to validate.

"""Numeric value as string"""
aoiGeometry: String!
customOptions: [ProjectCustomOption!]
imageProvider: StreetImageProvider
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might require a migration.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

return firebase_models.FbMappingTaskStreetCreateOnlyInput(
# XXX: converting this to int for backwards compatibility
taskId=int(task.firebase_id),
taskId=task.firebase_id,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still cast it to int for backward compatibility if the provider is Mapillary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants