deckerst / aves

Aves is a gallery and metadata explorer app, built for Android with Flutter.
BSD 3-Clause "New" or "Revised" License
2.75k stars 105 forks source link

Add drilldown such that Country > State > Region of most photos #70

Closed petazonk closed 1 year ago

petazonk commented 3 years ago

I love the breakdown of photos based on countries! It would be great if you could then click a country and it would break down by the states in that country and then within the state it would allow you to drill down to the region where you have taken the most photos.

deckerst commented 3 years ago

I'll probably try someday the drilldown Country > State, but not further.

As for your need, may I suggest you try the "Stats" page? For example, after selecting a country, you're on the Collection page with photos from the selected country. From there, go to the top right menu and select "Stats". You will see a section "Top Places", ordered by the number of photos. You can tap on the region to see related photos.

https://user-images.githubusercontent.com/13898333/133220523-af250d96-c98f-41ec-b2cc-28092fa4cfca.mp4

IzzySoft commented 2 years ago

Funny. On my test device I don't see that break-down. Could it be it only shows up when there are photos from different areas of a given country available (and not all are from the same city)?

deckerst commented 2 years ago

@IzzySoft which breakdown are you referring to? The country page? The stats page?

If you check out the Info page of an item with GPS coordinates, do you see something like the following? Screenshot_20221103_131113_Aves

IzzySoft commented 2 years ago

which breakdown are you referring to?

The one you described in your screen recording. So: "Menu › Countries › pcik the country › Stats". I get no "top places" (it's a test device, so just 5 photos from very close locations, nothing tagged).

If you check out the Info page of an item with GPS coordinates

Just the labels "JPEG" and "Camera". Then the map, coordinates, and the address only stating "DEU" – ah, there's the culrpit maybe? Something wrong with Nominatim? Can I trigger that somehow (and if it does not work check logcat)? The map shows the exact location fine.

Specs: Shift6mq running ShiftOS-L (G-free Android 10) with microG, Nominatim Backend is installed, configured (using OSM API Server) and activated. Not sure how I can test it.

deckerst commented 2 years ago

Reverse geocoding calls are heavy, so i skip them if i expect them to fail, and i thought they would fail for sure if the Play services are not installed. Your setup proves me wrong!

I do reverse geocoding in 2 steps: 1) first, a coarse pass that uses a topological map to quickly derive countries from coordinates. With that pass i don't have the full country name (e.g. "Germany"), just the code (e.g. "DEU") 2) then, another pass that calls the reverse geocoding api from the device to get the full address, from which i extract the country name and the place (e.g. "Berlin"). This pass is quite long.

From what you tell me, you have the country thanks to the first pass, but the second pass is skipped. Your reverse geocoding API replacement would likely work, if Aves was calling it.

IzzySoft commented 2 years ago

Your setup proves me wrong!

:smile: Your reasoning sounds well, though. Maybe introducing an option (default: off) one could toggle in such cases? And/or some button to trigger the 2nd pass manually if it didn't happen, measure it, and offer to enable it in general if it seems to work fine? Or some menu item to trigger a "batch run" for all photos missing those details?

Btw: Do you store those details back to Exif then, or keep them in a local database?

Preparing my photos on my PC for my "web gallery", I use the OSM Nominatim API from a Bash script (not sure if it is the very same). It needs some delays between calls there (at least if you have no API key IIRC), so on large collections it would take quite some time. Let me check… Oh, interesting. I had no delays in the calls to OSM; the 5s delay I remembered was for the GisGraphy API (results were easier to parse from that). So with the Nominatim backend microG is using, it could "simply work".

Your reverse geocoding API replacement would likely work, if Aves was calling it.

I happily test it out for you if you give me the means for it :smiley: Should go like butter for said test device (less than 10 photos), but I could try it on my other devices as well: an old FP2 running Android 11 (32bit), and my Wileyfox Swift still sitting on Android 8.1 (64bit) as I delayed the updates for so long (planned after I converted my Shift6mq to replace it).

deckerst commented 2 years ago

Do you store those details back to Exif then, or keep them in a local database?

In a local DB. That said, in the upcoming version of Aves, users can tag back items with the country and/or place detected by the app. See:

I happily test it out for you if you give me the means for it

Thanks! I'll make a temporary build for you to try, when i get back to a computer.

IzzySoft commented 2 years ago

Fantastico :smiley: Just let me know when and where to pick it up.

IzzySoft commented 2 years ago

@deckerst Not pressing, just wondering: About when could that be?

deckerst commented 2 years ago

Here's a temporary build. You can install this alongside the normal app. Changing settings in that build won't change settings in the normal app.

For that build, I just lifted the requirement to have play/huawei services installed to perform reverse geocoding calls.

IzzySoft commented 2 years ago

Thanks! Let me see if my local blocker lets me get to that GDrive :see_no_evil: And no worries, I have nothing configured yet (as pointed out, Aves is currently only installed on my test device which I'll soon™ will reset anyway to make it ready as daily driver), so no settings to be lost.

OK, got it (just took me 5 tries :see_no_evil:). I see no difference. Would I need to do something to initiate a scan for reverse lookup's second pass? Or is there anything I should watch out for (logcat etc) why it doesn't trigger itself?

(Gaa! Trying to find a button I stumbled on even more cool features – didn't notice the map with "other images near to this". Aves will most definitely replace the gallery on my device, drilldown or not :heart_eyes:)

deckerst commented 2 years ago

Would I need to do something to initiate a scan for reverse lookup's second pass?

Is it connected to the internet? If it is, I expected it to run the pass. Maybe you'd need to go to the Collection page menu, and tap Rescan.

Trying to find a button I stumbled on even more cool features

My advice is to tap all the buttons! ^^

IzzySoft commented 2 years ago

Is it connected to the internet?

Yes.

I also just enabled debug. Related details I see in Entry: "hasFineAddress: false". DB: adminArea & locality are empty. No idea what else to look for.

Maybe you'd need to go to the Collection page menu, and tap Rescan.

Did that already, but let me try again (with logcat this time). Hm, nothing related in logcat. Funnily, PCAPDroid doesn't report any network connections either. Oh, now, a bit delayed (Aves loading a bunch of tiles from OSM – which proves the network connection being fine). Maybe something that would explicitly trigger the second pass with some logging/debug? (No idea how to tell whether Nominatim works properly at all, so it might also be just that)

My advice is to tap all the buttons!

Will do, aye!

deckerst commented 2 years ago

Here's another build. It's the same behaviour, but i've added a few traces you should see in logcat (some lines starting with "TLAD", and some geocoder error logging).

If you see something like TLAD GeocodingService getAddress, Aves is calling the platform, and then you should either have a geocoder error log, or it works (and i guess some network activity).

IzzySoft commented 2 years ago

OK, if this is still true, the NominatimGeocoderBackend seems no longer be working (confirmed in multiple places), couldn't find the string in logcat – nor is the mentioned SelfCheck present anymore it seems :cry: Further, it's last release was more than 5 years ago…

You've mentioned limitations, and this issue seems to confirm it ("became useless due to introduction of API keys" – but then, I did not even see a request being sent via the network), but also mentions an alternative maybe Aves could adopt:

[reverse geocoding] can be implemented with Natural Area Coding System. Neither database nor network is required simply transform coordinates into a NAC string. For me, for example, it would be enough since all I want is to use "Location" sorting (grouping actually) in my gallery.

No idea about how practicable that is, though…

Thanks for the new build! Tested and confirmed my findings:

TLAD AvesEntry locatePlace AvesEntry#0d3bd{id=12, uri=content://media/external/images/media/13, path=/storage/emulated/0/DCIM/Camera/IMG_20221014_121848.jpg, pageId=null}
TLAD GeocodingService getAddress coordinates=LatLng(latitude:48.1xxxxx, longitude:11.5xxxxx)
Report error with exception=PlatformException(getAddress-network, failed to get address because of network issues, Service not Available, null), stack=#0      StandardMethodCodec.decodeEnvelope  (package:flutter/src/services/message_codecs.dart:653)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:296)
<asynchronous suspension>
#2      GeocodingService.getAddress (package:aves/services/geocoding_service.dart:16)
<asynchronous suspension>
#3      ServicePolicy.call.<anonymous closure> (package:aves/services/common/service_policy.dart:41)
<asynchronous suspension>
IzzySoft commented 2 years ago

I've raised a question for some Alternative to UnifiedNlp's Nominatim Backend at Software Recommendations – including that a fitting library for Aves would also be worth mentioning. Maybe something helpful shows up :crossed_fingers:

deckerst commented 2 years ago

Good to know, and thanks for checking!

Nit: in your stack exchange post, you mention GeocodingService getAddress but it's actually my homemade intermediate service. The Android class is called Geocoder. You can see how i check/instantiate/call it here.

IzzySoft commented 2 years ago

but it's actually my homemade intermediate service

Which is why I left out the dot (I hopefully did leave it out, didn't I? ah, I did, good) It's a speaking name ("call whatever GeocodingService is available and ask it to get the address). I also did not format it as code, for this very reason. But thanks for checking!

Meanwhile: do you think that NACS stuff could work? After all, we don't need to break down to the exact centimeter; I wouldn't drill down deeper than city level.

I also could look up the calls I use with my local shell script (you'd basically just need the HTTP request part) if you're interested and might consider including it as fallback. It's a simple call to https://services.gisgraphy.com/reversegeocoding/search?lat=${lat}&lng=${lon}&format=json which returns a JSON. You could then simply pick countryCode (which you already have), state and city from the first result (it goes down to geocodingLevel which with above sanitized coordinates is "house number").

deckerst commented 2 years ago

NACS is a coordinate coding system, an alternate to latitude/longitude, but not a system to get human readable addresses.

gisgraphy is not an option for Aves, because of the terms.

IzzySoft commented 2 years ago

not a system to get human readable addresses.

Oh, funny. Then that post in the Nominatim ticket is misleading.

because of the terms.

WTF… They are confusing. You can use it on your website, but not with a web service or script – how's that then supposed to work? OK, not an option for Aves then, I agree. And what I use as fallback you probably know already: https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&addressdetails=1&zoom=13&accept-language=de_DE – details a.o. here. Their terms state: "Use that is directly triggered by the end-user (for example, user searches for something) is ok, provided that your number of users is moderate." (also see the "Bulk Geocoding" section) And it has a limit of 1 request per second. Could work if e.g. only used when the user explicitly triggers a rescan, and requests are then throttled accordingly?

Skimming the terms I'd say that would fit. Note that the zoom=13 can be omitted, and the API then would even give more details (which IMHO would not be needed for the purpose on hand). accept_language could be set based on the users' language settings.

deckerst commented 2 years ago

There's no need for the app to choose an implementation. The app simply calls the standard system Geocoder. If some users choose to disable the built-in services that provide an implementation for the Geocoder, they can provide any alternative they like on their device, but adding or fixing backends for UnifiedNlp is out of scope for Aves.

IzzySoft commented 2 years ago

If some users choose to disable the built-in services

Hm, I didn't disable anything. I just chose a device coming without GApps :man_shrugging:

they can provide any alternative they like on their device

I'd like if there was any (hence my question on SR; let's see what that brings up, if anything).

but adding or fixing backends for UnifiedNlp is out of scope for Aves.

I understand that, thanks – still I was hoping you might consider it. Would Aves use those details if they were available in the Exif data? I'm thinking about the possibility of another app to add those details there then, if I can find such an app.

deckerst commented 2 years ago

Would Aves use those details if they were available in the Exif data? I'm thinking about the possibility of another app to add those details there then, if I can find such an app.

As far as I know, Exif and XMP do not have standard locations for country name, city, etc. but IPTC does. That said, IPTC is becoming an obsolete standard, being replaced by XMP.

IzzySoft commented 2 years ago

Oh, OK – good to know. So if it were there, would Aves use it? Might be easier finding and convincing a dev to write a re-tagger than an UnifiedNlp back-end :wink:

SigmaBonder commented 2 years ago

Here's another build.

Could you upload it again? I'd like to test it as well.

deckerst commented 2 years ago

@SigmaBonder you could try this one. Not strictly the same build, but just like the other one it will try to call Geocoder if Geocoder.isPresent() returns true, regardless of GMS presence.

deckerst commented 2 years ago

@SigmaBonder actually, do not use my previously linked build, there was a bug in the analysis service. Use this build instead.

SigmaBonder commented 2 years ago

I have two phones with microG on it — it works on one, but not on the other. It works on the fresh install, though, so that other one may be somehow misconfigured (even though I have no idea why). The Nominatim backend uses default OSM API, so it, too, is working fine. I think you can add the changes, then, because it can obviously be useful for people with microG.

Ah, too late. :-) I can test the second build as well, if you'd like, but it doesn't change anything relevant anyway.

SigmaBonder commented 2 years ago

What isn't working, though, is the map view. Can the microG be the culprit here or do you need to change something in the Aves as well?

Scratch that. I didn't grant it network permissions. MicroG can use MapBox, though, so it might be a good idea to use it as a provider here, too.

deckerst commented 2 years ago

@SigmaBonder please open another issue for that, and fill everything (expectations, system info, etc.)

IzzySoft commented 2 years ago

Here it's a pretty fresh install as well, not much changed with the configuration. It's a Shift6mq running ShiftOS-L 3.9 (the latest G-free ROM from the vendors themselves), installed as user app, all checks show green. Should I try that specific build again as well to see if it changed something?

deckerst commented 2 years ago

@IzzySoft i don't think it will change anything. i'm still curious why it works in some cases and not others, though.

IzzySoft commented 2 years ago

I see. If you have an idea and want me to give it another try, just let me know. I'm as curious as you are.

Btw, I've asked Irfan (the author of "My Location") to integrate Nominatim with his tests. The answer was cryptic to me (looks like the comment was lost and just the link remained), but maybe can give you a clue:

https://github.com/microg/UnifiedNlp/blob/master/api/src/main/aidl/org/microg/nlp/api/GeocoderBackend.aidl

Does that ring any bell with you?

IzzySoft commented 2 years ago

Bummer. Tried that last build of yours, @deckerst – as expected no change on the Shift6mq. Installed it on my FP2 (running LineageOS 18.1/Android 11 with microG integrated), and there it works…

ale5000-git commented 2 years ago

@deckerst Hi, could you please tell me how you detect the presence of Google Play Services?

deckerst commented 2 years ago

On my side:

    final result = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
    _isAvailable = result == GooglePlayServicesAvailability.success;

That call goes to this intermediate plugin:

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
...
      GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
      final int connectionResult = googleApiAvailability
          .isGooglePlayServicesAvailable(applicationContext);
ale5000-git commented 2 years ago

I can't test right now but it should succeed on microG: https://github.com/microg/GmsCore/blob/87465cd1dda13af39bfbe9f3ca11f259458d2820/play-services-base/src/main/java/com/google/android/gms/common/GoogleApiAvailability.java#L160-L164

SigmaBonder commented 2 years ago

Maybe we should move over to NominatimGeocoderBackend repo to not spam unrelevant issue? For now, though, relevant logcat fragment (I don't have enough knowledge to assess if this could be helpful, unfortunately):

11-09 07:32:14.888 17293 17293 W GooglePlayServicesUtil: deckers.thibault.aves requires the Google Play Store, but it is missing.
11-09 07:32:14.889 17293 17336 I flutter : Device has Google Play Services=false
ale5000-git commented 2 years ago

@SigmaBonder Do you have FakeStore or Play Store installed? It won't work without it. If you use FakeStore it must be v0.1.0 (or later).

If it is like this we already discovered the cause and there is nothing to fix.

SigmaBonder commented 2 years ago

@ale5000-git I had version 0.0.2 of FakeStore, as I just grabbed the latest stable version. I have just updated and everything works on normal Aves version. You are quite correct that there is nothing to fix then and @deckerst can keep the current code as well.

ale5000-git commented 2 years ago

The version 0.0.2 is incompatible with new Android versions, it won't be seen by apps. It didn't have the forceQueryable flag so apps won't see it as installed.

SigmaBonder commented 2 years ago

Good to know, I'll replace it in my builds. It's great we sorted this out!

ale5000-git commented 2 years ago

Still it won't be able to work if someone is using a standalone UnifiedNlp (without microG) but I think is a minority.

IzzySoft commented 2 years ago

I have FakeStore-v0.1.0.apk installed on both devices. Still only works on one of them.

IzzySoft commented 2 years ago

Yay! FIXED :partying_face: It indeed was a problem in the ROM (see here for details). I now can drill down to city level, and see the full address displayed below the map. Stats now also show "top places" on the SHIFT6mq. The fix will be part of the next OTA expected to ship very soon™ (rumors say within a week from now).

deckerst commented 1 year ago

@petazonk no drilldown from the country page yet, but in the next release there will be improved support for states (for now in AU/GB/IN/US). You can check out the following issue for some explanation and screenshots:

deckerst commented 1 year ago

Example of state breakdown, coming from the Countries page, selecting India, then Show states in the menu: