Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider embedding interactive map as <iframe> into "Country - Map" note type (Extended deck version) #638

Open
helitopia opened this issue Jun 30, 2024 · 26 comments
Labels
structure Templates, tags, generated decks, etc.

Comments

@helitopia
Copy link
Collaborator

First just wanted to say what a wonderful thing this repository is for people that want to raise awareness of the countries and their details in the world!

I have recently upgraded to extended deck version for the sole reason of presence of "Country - Map" note type. But, unfortunately opposite to what I expected, in this type of notes you can't really see the whole map and zoom in on the country as if you have "chosen" it. You only see a general globe.

This led me to looking for a solution and I found one! I edited note type to provide a link to the map with all names and other stuff removed - only land is visible. For example:

drawing

Here is the map link that I currently use: https://www.atlist.com/showcase/world-map-with-no-labels

And now I realize that it would be even better to embed this interactive map as iframe into this note type so that it would not even be necessary to open separate browser page for a map and switch to it.

Creating the issue to ask whether it is a good idea. If so I can try to create a PR with the change and we will see whether it is any good.

@helitopia helitopia changed the title Consider embedding map as <iframe> into "Country - Map" note type (Extended deck version) Consider embedding interactive map as <iframe> into "Country - Map" note type (Extended deck version) Jun 30, 2024
@aplaice
Copy link
Collaborator

aplaice commented Jun 30, 2024

Thanks for bringing this up! It's a very interesting idea!

Just to make sure: the point is to embed an interactive, unlabelled (but with country borders) map on the front side of the "Country - Map" cards? (So that one just has to "choose" the country from a visible map, rather than visualising the map oneself.)

(Aside: this is also interesting because it helps narrow down the goal of the "Country - Map" cards, which is rather than unclear with the current design (that has long bothered me) — whether it's a) to be able to locate the country on a map, b) to be able visualise the country's borders, c) to be able to visualise the country's borders and its neighbours, d) something else. Here it'd be clear that it's just a.)


Unfortunately, there are many probably-hard-to-resolve issues (see below) that would make me very hesitant accepting such an iframe solution into the main extended deck. (If Anki had a convenient global opt-in/opt-out mechanism then many of these wouldn't hold, but unfortunately it doesn't.)

However, an alternative approach would be for this to go into a "variant deck" (e.g. we'd have ~ "experimental extended deck with interactive map" in addition to "standard" and "extended" (probably just for English and/or some small subset of languages to avoid an n×m proliferation of decks)), where the barrier to entry would be much lower (though the flipside would be that the deck would likely also have far fewer users) — i.e. in effect an internal soft fork (if that makes sense) — if that's something that you'd be interested in.


Issues with iframe solution

  1. Bandwidth on mobile

    Could work around this by having the iframe only load if one presses some button, but that makes it far more annoying/removes much of the advantage over the "open in browser" solution.

  2. Security

    In principle, Anki(Droid|Mobile) has the cards in a sandbox, but especially for older versions it might be easy to escape from, so loading content from a not-necessarily-trusted website is problematic, unless the user clearly opts in.

    (Similarly for privacy — most people won't care, but some will very strongly.)

    (Here unfortunately the "hide behind button" solution wouldn't be sufficient.)

  3. Terms of Service

    I'm not sure whether using such an iframe is in line with Atlist's and Google Map's ToS.

  4. Licensing/free culture/software

    Some of our contributors care very strongly about this deck being free culture, and using atlist.com would collide with this. Having this in a variant deck would IMO be OK-ish, though.

    (There probably is some appropriately-licensed alternative, but if we're sticking to a variant deck, I'm not sure if it's worth the effort to find it/make sure that it's as convenient etc.)

  5. Consistency with our maps

    (Style-wise and borders-wise.) (Would be very-nice-to-have but not essential.)

Of these 1, 2 and 4 wouldn't hold for a variant deck (the user would be clearly opting in), 3 might still hold (but since it'd be an experimental variant, it'd arguably be less of a ToS violation?) and 5 isn't essential.

(Sorry for the wall of text — didn't have time to make it any shorter...)

@helitopia
Copy link
Collaborator Author

If Anki had a convenient global opt-in/opt-out mechanism then many of these wouldn't hold, but unfortunately it doesn't.

Could you elaborate please? What do you mean by "opt-in/opt-out"?

However, an alternative approach would be for this to go into a "variant deck"

  1. Just to be clear, the idea of the "variant deck" is to gauge users feedback and if everything works out great (and all the critical points are solved) then merge it into extended deck?
  2. As long as additional deck variation is not burdensome to support I am all in 🙂

Just to make sure: the point is to embed an interactive, unlabelled (but with country borders) map on the front side of the "Country - Map" cards? (So that one just has to "choose" the country from a visible map, rather than visualising the map oneself.)

Exactly! Here is what I managed to get for temporary use:

As you see from the gif, the issue with embedding the link I attached is 1) Slow loading (relatively); 2) Unnecessary labels displayed

Additionally, I've performed a bit of research and the points 3 and 4 (ToS and Licensing) are actually problematic with the map, link to which I attached - according to their pricing model users are billed by views of their map, if I understand correctly. So, unless we want to bring someone in deep debt, we might not use this map. Moreover, the user might delete the map from the profile at any time, bringing the whole idea down

I see 2 alternatives to the aforementioned issue:

Usage of open-source map API with labeling (i.e. country names) removal.

I've researched this idea a bit and there are certain providers of maps like OpenStreetMap that allow to make use of their map with the requirement of crediting them

The only thing left to figure out is whether I will be able to apply some filters to display non-labelled map. There is JS library called Leaflet that is explicitly stated as mobile-friendly. Its intention is exactly to make use of open-source maps. If I manage to figure out how to make it work, even mobile users might benefit from this idea as there should not be performance issues. Note, that point 1 (Mobile bandwidth) remains

HTML Canvas

This idea came to me literally today as a complete turnover from the previous one of embedding labelless map cards.

Instead of providing interactive map and make user "choose" the country with already existing border, we might provide a picture of, say, borderless Europe in the canvas and the user is themselves responsible for highlighting the borders of required country and deciding on whether they did it correctly enough

The downsides I see is 1) Mobile under question; 2) The need to provide different canvases to different continents (probably even more, as there are some islands far from the continent); 3) User is not required to interactively look up the country (might impact the memory effect?)

As a general conclusion

First off, the initial idea is not valid enough (at least in its purest form, as is) and needs to be improved by either (but not restricting to) of the alternatives stated (though as a hacky way it still works and I think I might continue using it until there is better solution)

Revisiting your points assuming first idea is to be implemented (OS map API usage):

  1. Bandwidth on mobile - needs to be worked around. A button on every card as you stated is annoying, right. If there were a way to tick a setting option, whether to show map link or to automatically show interactive map for all the cards - would be great. The only way I see now is via plugin somehow. AFAIK Plugins are not supported in AnkiDroid yet. As for AnkiMobile - I have no clue, not an Apple user
  2. Security - may be less of an issue as we work with open-source software. Gets eliminated completely assuming introduction of variant deck
  3. Terms of Service - as stated earlier, using the map is not an issue as long as we credit the creators
  4. Licensing/free culture/software - using OS software eliminates the point altogether
  5. Consistency with our maps - API allows for certain tweaks, so in terms of color there might be actually something to adjust. Borders - I think not.

(Sorry for the wall of text as well, just trying to help improve something I admire)

@axelboc axelboc added the structure Templates, tags, generated decks, etc. label Jul 1, 2024
@aplaice
Copy link
Collaborator

aplaice commented Jul 2, 2024

Thanks very much for your detailed, thought-out reply!

Could you elaborate please? What do you mean by "opt-in/opt-out"?

I mean more-or-less what you wrote here:

to tick a setting option, whether to show map link or to automatically show interactive map for all the cards - would be great.

at the very least as an overall per-user option (to apply everywhere for the given user).

(Preferably there'd be easy access to a toggle (so that users can quickly switch between having it displayed/not displayed), and ideally it'd be on a per-platform basis — so that users can, say, choose to always have the map displayed on desktop but never on mobile; however these are even less likely.)

One simple-ish (at least for the more technically-inclined users..) approach that I missed earlier might be to control the loading of the interactive map with a variable in the JS code, along the following lines:

// With nicer function/var names

const shouldLoadInteractiveMap = false; // switch to true to opt-in

function loadInteractiveMap() {
    // create iframe or apply whatever approach we choose
}

if (shouldLoadInteractiveMap) {
    loadInteractiveMap();
}

Unfortunately, this is very user-unfriendly for the non-technically-inclined, and possibly even less convenient than just using a variant deck.

(Aside: using localStorage to store user preference doesn't work (like I hoped it might) as it's currently not persisted on either Anki or AnkiDroid.)

  1. Just to be clear, the idea of the "variant deck" is to gauge users feedback and if everything works out great (and all the critical points are solved) then merge it into extended deck?

Yes, gauge user feedback and merge if critical points are solved and users like it (but keep it as a variant otherwise (in effect as a heavy opt-in mechanism)). (Note that the points I've brought up are my viewpoint. My co-maintainers might have more stringent or more relaxed opinions and depending on user preference we might also adjust what is considered critical (in either direction), so I'm not making any promises regarding inclusion into the extended deck.)

I see 2 alternatives to the aforementioned issue:

Usage of open-source map API with labeling (i.e. country names) removal.

I've researched this idea a bit and there are certain providers of maps like OpenStreetMap that allow to make use of their map with the requirement of crediting them

The only thing left to figure out is whether I will be able to apply some filters to display non-labelled map. There is JS library called Leaflet that is explicitly stated as mobile-friendly. Its intention is exactly to make use of open-source maps. If I manage to figure out how to make it work, even mobile users might benefit from this idea as there should not be performance issues. Note, that point 1 (Mobile bandwidth) remains

Yeah, I don't think there's a way around a setting option of some sort.

(Very crazy) local map

A very crazy idea would be to store the JS library and all the tiles locally (in the deck!). Since we don't need to have high zoom levels, the amount of tiles might be just about feasible.

To get a feel for the potential data size, the Organic Maps (offline maps app) "WorldCoasts" mwm file is 8 MB, while the "World" file is 46 MB. The "World location map" SVG file on Wikipedia is 5 MB. For comparison, all our AUG image files are currently 16 MB. The amount of detail available in the World Map on OM (without extra data files) is slightly greater than what we need, and the detail in the SVG file is about right, so maybe we could manage without ballooning our media size?

Clearly, this would also be very hard to get to work, since we'd be embedding everything...

(It seems that XMLHttpRequests from an iframe to a file in the Anki media folder do work, at least on Anki 23.12, so it probably is technically doable.)


HTML Canvas

The downsides I see is 1) Mobile under question; 2) The need to provide different canvases to different continents (probably even more, as there are some islands far from the continent); 3) User is not required to interactively look up the country (might impact the memory effect?)

There's also the issue that by displaying different canvases we'd be telling the user which continent the country is on. Also, for larger continents like Asia a single canvas might not be detailed enough.


As a general conclusion

First off, the initial idea is not valid enough (at least in its purest form, as is) and needs to be improved by either (but not restricting to) of the alternatives stated (though as a hacky way it still works and I think I might continue using it until there is better solution)

I'm glad that at the very least you have an ok-ish approach for your personal use! :)

Revisiting your points assuming first idea is to be implemented (OS map API usage):

  1. Bandwidth on mobile - needs to be worked around. A button on every card as you stated is annoying, right. If there were a way to tick a setting option, whether to show map link or to automatically show interactive map for all the cards - would be great. The only way I see now is via plugin somehow. AFAIK Plugins are not supported in AnkiDroid yet. As for AnkiMobile - I have no clue, not an Apple user
  2. Security - may be less of an issue as we work with open-source software. Gets eliminated completely assuming introduction of variant deck
  3. Terms of Service - as stated earlier, using the map is not an issue as long as we credit the creators
  4. Licensing/free culture/software - using OS software eliminates the point altogether
  5. Consistency with our maps - API allows for certain tweaks, so in terms of color there might be actually something to adjust. Borders - I think not.

I agree that the OS map approach is promising. (Definitely something we'd want for a variant deck, and IMO for the main deck if we find a convenient "setting option".)

@axelboc
Copy link
Collaborator

axelboc commented Jul 2, 2024

I'm keen on the idea of storing an SVG world map in the deck. I feel like we might even be able to make it interactive with a bit of JS so users can zoom in and tap on the country to answer. Maybe another shared deck has already done something this?

@axelboc
Copy link
Collaborator

axelboc commented Jul 3, 2024

This seems promising: https://jvm-docs.vercel.app/

@helitopia
Copy link
Collaborator Author

helitopia commented Jul 3, 2024

This seems promising: https://jvm-docs.vercel.app/

Amazing finding!

From a first glance at the docs, the library provides a lot of the features that fit the issue needs:

  • Region and Marker concepts can handle the definition of countries and capitals
  • onRegionClick, onMarkerClick events can be probably used to explicitly interactively select a country / capital
  • Custom countries can be generated, though the linked project seems a bit abandoned

Just a note from a few days of usage of interactive content on AnkiDroid: It is horribly incompatible when there are certain gestures set up in the card reviewer (e.g. "Undo", "Edit note").

@helitopia
Copy link
Collaborator Author

helitopia commented Jul 4, 2024

@aplaice, @axelboc

If you don't mind, I will take the things discussed into consideration and start the research of the library mentioned above with further development

I think I will get back with updates once in a while. Just note, that it won't be quick (think a month or so) as I am not the fast one 🙂. Having other things on the agenda does not help either. So if it is such a revolutionary thing that needs to be done immediately, then probably it is beneficial if someone else volunteers to take control of development.

@aplaice
Copy link
Collaborator

aplaice commented Jul 4, 2024

It's definitely not revolutionary/urgent — take as long as you need!

Thanks very much for looking into this!

@helitopia
Copy link
Collaborator Author

helitopia commented Jul 15, 2024

Hi @aplaice, @axelboc

Getting back with updates on the current implementation status.

Please, take your time going through the comment, it is another long-read, this time with all the technical details 🙃.

Here is a raw example of a card of "Country - Map" note type (Refer to PoC section for code):

Anki Desktop (Windows):

AnkiDroid:

User is suggested to pick a country from the map. After picking a country card gets swapped automatically, zooming in on the correct answer.

Emphasizing on the adjective "raw" as there are a lot of things to be clarified/adjusted

Here is a list of notes/questions/ideas:

Note (# 1 - Baseline change):

First of all, for such solution to work there is a need to introduce a way for JS code to highlight correct region on answer. In PoC in was achieved by setting "Map" field to appropriate region code:



Note that field "Map" was chosen arbitrarily. Effectively as long as there is a way to retrieve region identifier in note template JS code (script tag) any field (or any other solution) will do.

Note (# 2 - Region border width limitation):

In the PoC demo you can see that the style of map coloring was attempted to be maximally preserved. Still, borders of regions look excessively wide relative to the map viewport, unfortunately with current API there is no way to make them any more thinner (see Note #5 section for proposed solution).

Note (# 3 - Crossplatform compatibility):

The PoC was tested on both Anki Desktop and AnkiDroid. Unfortunately I am not able to get my hands on AnkiMobile app (IOS). Probably will need help from fellow Iphone users.

Note (# 4 - Local library storage):

As initially hinted by @axelboc, the library is easily stored locally. This eliminates bandwith problem completely, while optimizing the performance to the maximum.

The PoC is using code of the library from collection.media folder which is automatically synchronized without the need to install it on every device separately.

Note (# 5 - Library limitations, solution):

As an aside, the library lacks a lot of useful features / contains certain bugs. For example:

  • Lack of extensive border width control
  • Drag on mobile bug
    • For dragging on mobile to work tooltips should be enabled
    • In the PoC tooltips are enabled on question side, but style is set to hide them. This is effectively a "hack"
  • Additional maps (see Note #6 section)
  • Ability to highlight multiple regions with different colors (see Note #7 section)
  • Other minor rendering bugs

Some of them have corresponding issues on the GitHub page of source code. Apparently, code maintainer is aware of them, just quite busy to implement the changes.

I have became quite familiar with codebase of the library (as documentation does not describe all the details properly there is a need to dive deeper) so I think I will contribute to it with fixes/updates at some point. Just not sure if maintainer will accept them soon as it feels the author rarely patches up the repo nowadays.

Since the library is intended to be stored locally (including SVG maps) one of the solutions is to include a fork (instead of master version) with agreed critically needed features/bug fixes added (if any) in case of their delayed acceptance into original codebase. The idea is further solidified by the next section

Note (# 6 - Additional maps)

There is a number of reasons behind the motivation to create extended maps aside from the "world.js" (further - default map) provided by library author:

  • No continents in default map
  • No oceans & seas in default map
  • General alignment with current map view (e.g. Kosovo, South Ossetia)
  • Certain notes require choosing of a geographic entity not present in the default map
    • e.g. Corsica is a part of France, Sicily is part of Italy, no Azores in default map

The concept(not yet included in the PoC) is to programmatically decide to show to the user a map depending on the region specified in the note. For example:

  • Separated Sicily world map for "Sicily" note
  • Map of oceans & seas for "Black sea" note

It is proven to be programatically achievable (tried it). The major implementation detail is storing JS Map with (region identifier, map path) pairs and load the corresponding map based on the region

In case points stated above are valid it needs to be discussed what maps to create.

Thoughts on the subject?

Idea (# 7 - Green/Red answer):

It is possible to make coloring of a region on answer either red or green, depending on whether the answer is correct to visually aid user:


Although ideally in case of incorrect answer two regions should be highlighted - selected in red and correct in green. But, again, the library right now lacks the ability to highlight regions with different colors (see Note #5 section).

Thoughts?

Idea (# 8 - Capitals on map):

The library allows for "Markers" feature:

I understand the idea is significantly remote from the current issue, but still worth considering:
Addition of same logic to note type "Capital - Map" where user is prompted to select location of a capital among all the markers.

Not an immediate thing to discuss, just a matter of thought for the future.

To summarize:

The concept and underlying implementation library have proven to be promising, although require a lot of work to be adjusted to the project's needs - thus such a long-read comment with so many points

Proof of Concept (PoC)

Codepen: https://codepen.io/helitopia/pen/BaeErdz
(adjusted to showcase both card sides)

Sample deck: https://github.com/user-attachments/files/16232607/UG_Anki_PoC_jsvectormap.zip
(Contains a single card. Import the deck (.apkg), make sure that _jsvectormap.js, _jsvectormap.min.css and _world.js are imported into collection.media folder. No conflicts with original UG deck should arise)

Direct notetype code:

@aplaice
Copy link
Collaborator

aplaice commented Jul 26, 2024

Hi @helitopia

Sorry for the very late response!

Firstly (limitations aside), this is really, really cool and it looks like a huge amount of work! :)

For a "raw" implementation it works quite smoothly and nicely!

Note (# 1 - Baseline change):

First of all, for such solution to work there is a need to introduce a way for JS code to highlight correct region on answer. In PoC in was achieved by setting "Map" field to appropriate region code:

Yeah, we can add a "Region code" field (we can bikeshed names later :)) or if we completely remove the static map just repurpose the "Map" field like you did. (If we really don't want to add an extra field with region codes, then I'm sure that we could have a lookup table/dictionary, for country names to region codes, but IMO that'd be over-complicated, especially given multilinguality.)

Note (# 2 - Region border width limitation):

In the PoC demo you can see that the style of map coloring was attempted to be maximally preserved.

You've managed to replicate the style of our maps quite accurately!

Note (# 3 - Crossplatform compatibility):

Probably will need help from fellow Iphone users.

Unfortunately, I only have access to an ancient iPad (with iOS 9 (current version is 17)), so I'm not much help.

Note (# 4 - Local library storage):

As initially hinted by @axelboc, the library is easily stored locally.

This is great! And it's great that it's already fully-local in the "raw" version! :)

Note (# 5 - Library limitations, solution):

Since the library is intended to be stored locally (including SVG maps) one of the solutions is to include a fork (instead of master version) with agreed critically needed features/bug fixes added (if any) in case of their delayed acceptance into original codebase.

Yes, in principle, I don't see any reason not to create and use our own fork of the library (though obviously trying to upstream everything, to the extent possible, like you suggest).

Note (# 6 - Additional maps)

Yes, using a custom map might also allow for the main map to have finer detail (the default map from the library is rather "angular" when you zoom in, and completely lacks many smaller islands (even island countries not just dependent territories and the like)).

Given that the default map is ~ 100 kB, we could probably easily have a resolution ~ three times bigger (for a file size of ~ 900 kB) or more. (No idea how difficult it's to generate an alternative map in the appropriate format for the library.)

Some potential problems:

  1. How to represent disputed borders accurately. (e.g. we'd want South Ossetia to (somehow) be both part of Georgia and an entity of its own...)

    (Ideally, we'd have something similar to what we have for our static maps — the blank maps could simply have dashed lines for disputed borders, and the highlighted maps would have "hatches" for disputes (not sure about hovering — highlight Georgia (with hatches) when hovering over undisputed (non-Abkhazia, non-Ossetia) Georgia and Abkhazia/South Ossetia when hovering over them??) — but given that highlighting two different non-overlapping countries is not currently available in the library, this might be very tricky...)

  2. How to avoid giving "hints".

    Having maps that behave differently (different hover behaviour and/or borders) for different classes of entities will partially give the answer away.

    For seas vs. land entities this isn't an issue (it's clear that they're different anyway). However, if you're, say, learning European countries/territories and the blank map is different for Scotland (split up UK) than for Ireland (not split up UK), you can pattern match when you look at the front card.

    I'd be almost tempted to just have the same blank (front card) map for all notes, and only different maps for the back card. This would unfortunately likely mean that we'd lose the ability of clicking/verifying answers, though.

  3. How to deal with hierarchical seas (e.g. the Aegean is part of the Mediterranean). This is a bit like 1 and like Sicily being part of Italy, but arguably worse (the Aegean and the Mediterranean aren't really qualitatively different like Sicily/Italy and you can't uniquely partition by "de facto" control like Abkhazia/Georgia).

TBH maybe we should just implemement only sovereign states as a first implementation??

Idea (# 7 - Green/Red answer):

Very interesting, not sure! Given the limitations of the library, maybe just have an option to display a textual message ("you selected Belarus"??)?? Would that be annoyingly verbose?

But while cool, I don't think that this is a priority — the user should know which region they just selected, and they can hover over it to find out what it was, so while nice, we don't have to display their selection.

Idea (# 8 - Capitals on map):

An extra Capital-Map card is interesting!

(FWIW I have a partial implementation of having static capital map cards (purely as auxiliary info on the current capital cards), that I haven't quite finished off, that I've been sitting on, for a while, but it's a different use-case.)


To summarize:

I think that one approach might be to initially just focus on UN-recognised sovereign states (and provide some static fallback in the other cases) to side-step the issue of hierarchical regions and alternative maps??

With a more detailed map and slightly narrower borders, I'd definitely want this as an experimental deck, even if we only have some subset of notes (and the borders deviate from our static maps)! (TBH I'd even want the current PoC as an experimental deck — I can imagine some people wanting to use the interactive map as a rough aide* — but the time spent tagging all relevant countries/integrating everything in might not be worth it for you, for now.)

* in terms of user-experience it's probably worse than an iframe like you were using (though on the plus side it's much, much faster), but for local-first/highly-privacy-oriented people it might be worth it

@helitopia
Copy link
Collaborator Author

helitopia commented Jul 27, 2024

Hi @aplaice

Thank you for the detailed review, I appreciate the effort!

All the thoughts and comments are noted.

TBH maybe we should just implemement only sovereign states as a first implementation??

I think that one approach might be to initially just focus on UN-recognised sovereign states (and provide some static fallback in the other cases) to side-step the issue of hierarchical regions and alternative maps??

TBH I'd even want the current PoC as an experimental deck

but the time spent tagging all relevant countries/integrating everything in might not be worth it for you, for now

I suggest a smooth start - integration of PoC in experimental deck for European countries only (with static fallback for everything else).

Edit: Europe is chosen solely on the basis of preference and assumed popularity among the users

While it is true, that the efforts exist for such work, there is a huge benefit - user feedback. Up to this moment we have discussed all the issues from theoretical perspective, when, from personal experience, it is really difficult to account for all the things that might go wrong in practice. This way we gain enormous advantage while contributing relatively (to the whole deck) low effort in case current PoC is flawed.
Moreover, if the PoC works fine and we proceed further to extend the map, we won't necessarily have to rework Europe part, as created map can be compatible, preserving region codes

And in the meanwhile I will continue to work on the subjects discussed + probable issues/suggestions obtained from users

What do you think?

@aplaice
Copy link
Collaborator

aplaice commented Jul 27, 2024

I suggest a smooth start - integration of PoC in experimental deck for European countries only (with static fallback for everything else).

Yes, that's a sensible start (and your arguments make sense)! (But that's up to you, as the driver of this effort!)

(I'm very happy to help if you have any questions about the slightly idiosyncratic way we arrange things, here, etc.)

@axelboc
Copy link
Collaborator

axelboc commented Jul 28, 2024

Fantastic work, thanks for providing so much details on your progress! The approach you both agreed on is also fine by me.

@josealberto4444
Copy link
Collaborator

josealberto4444 commented Aug 12, 2024

Hi,

I've been getting the emails about this issue and got a very rough idea of what was happening, but I just read this issue entirely and I'm very excited about all this. 😍 Tomorrow I want to read and take a look at the PR @helitopia did with detail.

Just in case it helps, I have access to an iPhone and an iPad of a friend that uses Ankimobile. If you need anything, ping me. I'll try to keep in touch with this development, but just in case I miss something. 🥰

@helitopia
Copy link
Collaborator Author

Hello @josealberto4444,

Thank you for the kind words! It is really surprising how a simple idea with <iframe> transformed into fully interactive map containing so many options.

Tomorrow I want to read and take a look at the PR @helitopia did with detail.

Currently we are working on final minor changes to the PR to properly prepare for the first release. Please feel free to ping me anytime anywhere if you have any questions.

Just in case it helps, I have access to an iPhone and an iPad of a friend that uses Ankimobile.

This is wonderful news! We will most definitely need someone to test the deck on AnkiMobile as unfortunately I don't have access to any IOS devices.

@helitopia
Copy link
Collaborator Author

helitopia commented Aug 22, 2024

Hi all,

Just as you probably thought "how much longer his comments can be" :)

Congratulations to everyone involved on the first experimental deck beta-release for this issue! 🎉

Getting back to the remaining agenda on this issue. The items below are listed in the high-to-low priority order (grouped by h1 sections). Please, feel free to complete the list with additional items I missed and/or to point out a better priority ordering.

The only question is whether it is better to leave them all in scope of this issue only or to separate each one into separate issue. IMO the latter option would encourage other contributors to participate as well by modularizing each task (in contrast to reading this already terrifyingly large thread).

Glossary

  • IM - interactive map
  • JSV - jsvectormap library
  • ZL - zoom level
  • UG - Ultimate Geography deck

Major milestones

GeoJson migration

Currently the world map in usage is generated based on SVG taken from the Web. This approach was first chosen due to its convenience.
Unfortunately, pre-made SVGs are lacking flexibility to be customized easily (e.g. to add an island one must think in terms of SVG coordinates rather than actual geographic coordinates)

To eliminate the issue the following map utilization workflow is to be introduced:

  • GeoJson files are the basis for maps in use
  • When certain adjustment needs to take place - the file should be changed via either:
    • importing it in any GeoJson UI (e.g. geojson.io) and editing appropriately
    • manually (or programatically) editing the direct file
  • After all the changes are implemented, the files should be converted into SVG and made compatible with JSV format.

The initial GeoJson can be created by either:

Custom maps implementation

After the previous step is done the process of completing map(s) to fit project needs should start.

The issue represents a large number of smaller sub-issues. See the following sections for details on each one.

Small-area regions interactability

The problem with selecting such regions (read islands) at the moment is that some of them have small area relatively to the fixed border width:

This is the reason (that is, absence of the solution) that current IM version limits maximum zoom level even though JSV allows it to be arbitrarily large.

The solution to this issue is introduction of JSV option to reduce border width proportionally to a certain ZL starting from its certain value and then allowing for much higher maximum ZL (large enough to select the smallest islands present in the map). For example, ZL: 10 -> border width: 1; ZL: 100 -> border width: 0.5. This way, small islands at large ZLs will look like a regular countries at moderate ZLs:

Water bodies and their hierarchy

Additionally to currently existing regions water bodies should be added.

As mentioned in the comment (section "How to deal with hierarchical seas"), there is an issue with the selection mechanism of water bodies that are fully inside other water bodies.

At the moment there is an idea for the functionality - at all times (independently of a card and its side) to behave as follows (on the example of Mediterranean and Aegean seas):

  • When Aegean sea is hovered / selected - highlight it
  • When Mediterranean sea is hovered / selected - highlight the whole sea, including Aegean one.

The possibility of this behaviour needs to be investigated in JSV.
Want to hear you thoughts on this subject in particular.

Disputed borders and separate regions

(Examples: Transnistria and Moldova, Corsica and France, Ireland and England)

In addition to solution described in "Water bodies and their hierarchy" section, two things need to be considered:

  • Setting region-partial dashed lines (disputed borders)

  • How to handle situation described in the comment:

    However, if you're, say, learning European countries/territories and the blank map is different for Scotland (split up UK) than for Ireland (not split up UK), you can pattern match when you look at the front card.

    Probably the idea should be the same - Scotland, England, Wales and Northern Ireland are always split up (to avoid giving hints). When card requests selecting, for example, Scotland, you do so. In the other case when United Kingdom - you select either of the 4 regions and on the back side the whole country is highlighted

This issue is probably the most complex in terms of required logic for implementation.

Continents

This one should be pretty straight-forward. Currently there are neither map separate for continents nor the logic to display it when corresponding card is reviewed. Creation of the map in a way discussed in previous sections (via GeoJson) and addition of logic to work with it are required.

Selected region pattern highlight

As was originally suggested ("Map colours" section) it is possible to employ the following selected region hightlighting schema:

  • Correctly selected region - solid red highlight color (unchanged)
  • Incorrectly selected region - pattern(e.g. zigzag) highlight color (in contrast to the current solid green)

As was further discussed in the comment (section "Patterns in regions"), JSV library in status quo does not natively support selected region pattern highlight.

The implementation of such logic is required. But before getting to it, it is recommended to assemble a PoC of the idea in order to understand whether the idea is of any good at all (and thus avoid doing extra work that might be discarded anyway).

Performance considerations

As mentioned in the main description of the initial PR:

Performance - higher-level detailization map slightly reduces performance by bringing delay between user event and action execution. The decrease will most likely go unnoticed by those who have not used previous low-detail map and is surely not critical, but this aspect should be taken into account in case of decision to move to even more detailed map (more on this in the original issue afterwards)

There is certainly a risk that any of the aforementioned changes may bring performance to the unusable level. Even if we do not introduce any more detalized maps than there currently exist, the JSV library still heavily relies on the ability to perform hube number of calculations. If we do stumble upon this issue, JSV codebase may be tried to be optimized.

To hell with it, I am even willing to rewrite it into WebGL for the sake of experience, but unless we plan to roll out a Google Maps competitor, just taking care and be mindful of the performance would be enough.

Other improvements

Edit: Incorrect selected and correct regions highlight

As was mentioned early on:

Idea (# 7 - Green/Red answer)

...
Although ideally in case of incorrect answer two regions should be highlighted - selected in red and correct in green. But, again, the library right now lacks the ability to highlight regions with different colors (see Note #5 section).

Currently, JSV does not allow for different selection styles of multiple regions. The intention of this item is to investigate the possibility of introduction of such logic.

Mobile media refreshing

At the moment it is unclear of the criteria by which AnkiDroid decides to refresh files from server into media folder (in particular IM scripts). The issue should be investigated further.

Mention of possible solution in the comment:

This is quite a problem if it affects end users. The easiest solution I can think of is a web development technique called cache busting, which consists in appending a hash of the file's content to its filename – e.g. _interactive_map_init_2d7fe.js.

is non-preferred due to the reason specified in the next after aforementioned comment:

Yes, it is. Will keep in mind the mentioned technique. Although the disadvantage I see is that with time and a series of updates user media folder will accumulate significant amount of older unused files (which are not removed by "Check media" option, due to those files being considered intrinsic as they are prefixed with underscore). They do not weigh much (at least now), but still.

Zoom animation max level

The problem with setting infinitely large zoom level (after "Small-area regions interactability" milestone is implemented) is that when region is animated to be shown (on the back card side), it will animate zoom up until a certain region fills either horizontal or vertical space leaving no context around the region.

Here is an example for Iceland:

Probable solution to this issue is a separate maximum zoom level (which is less than maximally allowed) when animating zoom on region show (and if user needs more context they can additionally zoom in / out)

Edit: Zoom animation abrupt reset fix

As discussed in the thread

AnkiDroid gesture disabling

When IM is used in AnkiDroid with enabled gestures, there is a conflict arising, making usage of one feature impossible without accidental interaction with the other. At the moment, to workaround this issue additional notice was written in the wiki.

To improve user experience and avoid making users disable gestures every time they want to review UG cards with IM in the note template, investigate the possibility of disabling gesture registering in the IM canvas.

Dark mode

Possibility of introducing a switch for dark interactive map mode (example - source). If agreed, region highlighting colors should be determined.

Configuration reset notice

With each experimental-to-experimental deck update the configuration of the user (in note template) is reset. Write the corresponding notice in the wiki page and add an item to instruction list stating that to preserve custom configuration it must be manually saved prior to the update.

Bugs

Global tooltip littering

Current version of the library inserts tooltip into body element of the page. During the Anki review session only part of the page is refreshed - in which the card (both its front and back sides) resides.

Such situation leads to a problem as shown tooltip is not erased between different card reviews, thus making tooltips accumulate, which is distracting to say the least.

Currently (commit 0f09943) this issue is resolved via separate function respondible for DOM manipulation:

  function clearTooltips() {
	commonElements.mapTooltips.forEach(x => x.remove());
  }

In the future it would be nice to have ability to specify parent element of the created tooltip when initializing JSV.

regionsSelectableOne over regionsSelectable

Currently when initializing JSV map regionsSelectableOne option works exclusively when regionsSelectable option is enabled. Logically, it is unnecessary tautology. Enabling only regionsSelectableOne option should work.

BrainBrew last line issue

While not being functionally significant, BrainBrew adds newlines at the end of each file it processes, which sometimes is outright redundant. Although I might miss the real reasoning behind such behaviour.

Swipe on mobile bug

Currently JSV library allows for swiping only when tooltip is enabled. This seems strange as two features are pretty unrelated. To workaround it the program enables tooltip and hides it (or not, if it should be enabled) on front card side:

  function mobileSwipingHack(tooltipEnabled, tooltipShowHandler) {
	return commonConfig.isMobile
  	? {
    	showTooltip: true,
    	onRegionTooltipShow(event, tooltip) {
      	if (tooltipEnabled && tooltipShowHandler)
        	tooltipShowHandler(event, tooltip)
      	else
        	tooltip._tooltip.style.display = "none";
    	}
  	}
  	: {
    	showTooltip: tooltipEnabled,
    	onRegionTooltipShow: tooltipShowHandler
  	}
  }

This should be resolved in the library codebase as eventually someone (other user of JSV) will report it anyway.

Ideas for future consideration

Code bundler employment

Assuming changes from previous sections will be implemented, it is worth considering to modularize the app and employ some code bundler (e.g. webpack) in order to tree-shake, remove comments from code and minimize it altogether. Although the space scripts occupy is not significant, in the long run IMO this will allow to maximally optimize size.

The idea is enforced by the ability to locally integrate (read hook) a tool to convert GeoJson into SVG into code bundler (or to complete the tool and make it produce JSV compatible format altogether).

Map - Country static replacement

As was asked in the comment:

Concerning the static images, won't they have to stay anyway for the Map - Country template? Or were you thinking of putting an interactive map on the front side of this template as well?

In the long run, it is probably worth considering to indeed utilize interactive map in mentioned template as well.

Benefits:

  • Providing more context to the user - allowing to move the map around, zoom in / out (or disabling the option, say, from configuration)
  • Possibility of static map elimination - although IMO a doubtful option as library may malfunction in any moment and solid backup is required. So if the space is not a concern, static maps are probably better off staying (in this case burden of their support stays as well).

Obviously, at the point this topic is started to be discussed the IM should be impeccable to provide all the regions in high quality.

Capitals

The subject has already been mentioned in the comment.

The idea is introduction of Capital - Map & Map - Capital note templates (or the integration of such IM into Country - Capital & Capital - Country templates to visually aid user in learning capital locations; or both).

The major motivation of the former (i.e. Capital - Map & Map - Capital note templates) is to learn not only the capitals themselves, but their location as well (just like we learn locations of countries through IM).

Here is a showcase of marker feature from JSV page:

States and provinces (level 1 administrative hierarchy)

As you probably figured from the previous section, IM opens up a huge space of possibilities.

The idea of the current section is to have states (or provinces; generalized as level 1 admin hierarchy) of countries as separate cards, which will allow the utilization of Map - Country and Country - Map templates for learning.

I guess for all these years you have received inifinite number of requests for expansion. This section is about "expansion of (yet to be performed) expansion" :)

Obviously, this and previous topics are thus heavily dependent on the #603 issue (and its origin, I guess - Brain Brew #4) - existence of Anki UI add-on to combine core UG deck and its extensions (i.e. cards with various states) is crucial.

To summarise

In general, after reading the whole agenda it might seem that it is a lot of work and it really is. But, nevertheless, I am quite eager to get the job done and would appreciate you support along the way.

@josealberto4444
Copy link
Collaborator

Thanks for summarizing all this. ❤️

I completely agree with the idea of splitting this in different issues or we will go crazy, haha. For example, I already have some comments about the highlight colors and the small regions interactability (the comment: it is already happening with Bahrain and Singapore).

@axelboc
Copy link
Collaborator

axelboc commented Aug 22, 2024

The only question is whether it is better to leave them all in scope of this issue only or to separate each one into separate issue.

Separate issues definitely, but maybe not for everything and/or not right away. This issue can remain open until we consider the interactive deck "stable". Once that happens, we can move all the remaining topics into separate issues to continue investigating and/or gather input from the community.

For shorter term stuff (like the colours/patterns), we (i.e. anyone) can open issues/PRs/discussions as needed:

  • PR to propose/discuss a solution right away (it doesn't have to be merged if it doesn't pan out);
  • discussion thread to discuss direction/scope/... before opening more targetted issues (e.g. custom maps) — note that there's already a thread to give feedback and report bugs on the initial version of the experimental deck;
  • issue when the bug/feature request is clear and agreed upon and we just need someone to work on it, or when we want to confirm that the community needs/agrees with it.

To hell with it, I am even willing to rewrite it into WebGL for the sake of experience, but unless we plan to roll out a Google Maps competitor, just taking care and be mindful of the performance would be enough.

A quick search led me to MapLibre, OpenLayers, and gleo... 😂 but I doubt they meet our offline requirement. Might still be worth exploring though.


Regarding prioritisation, here is my personal opinion:

  • I would make Zoom animation max level a priority, as I think context is really important. I also find it a bit disorientating in terms of UX to have the iframe filled up by the entire country on the back card, especially for small countries/territories.
  • I would make Mobile media refreshing a priority as well for the stabilisation of the deck.
  • Performance doesn't need to be a major milestone, in my opinion. That's also why I think it's worth keeping a static map solution: it's a good fallback solution for users with low-end devices.
  • I think your Custom maps milestone is worth splitting up in terms of priorities. I would consider the deck stable if we provided interactivity for one agreed-upon level of detail (e.g. either UK or its constituent countries, but not both). Similarly, the water bodies and continents can be seen as out of scope of a first stable interactive deck, IMO. The priority here for me is the border width issue at high zoom levels. (By the way, on this matter, have you heard of vector-effects="non-scaling-stroke"? It might not be supported by Anki's built-in browser, though.)

@helitopia
Copy link
Collaborator Author

helitopia commented Aug 22, 2024

For shorter term stuff (like the colours/patterns), we (i.e. anyone) can open issues/PRs/discussions as needed

Agreed on the workflow.

A quick search led me to MapLibre, OpenLayers, and gleo... 😂

My point was to show the dedication for the idea to succeed 😄. Anyway, as I said, it is rather extreme.

but I doubt they meet our offline requirement. Might still be worth exploring though.

Yeah, that and the fact that it will probably be less work (and more fun :)) to tailor JSV to our needs rather than to start from scratch with the new library.

By the way, on this matter, have you heard of vector-effects="non-scaling-stroke"? It might not be supported by Anki's built-in browser, though

Haven't heard of it before. Tried it, attaching multiple samples below.

stroke-width="1":

stroke-width="2":

stroke-width="3":

As you see from the samples, currently (with such ad-hoc solution) border width is the same as on static images when either:

  • fully zoomed out (stroke-width="1")
  • average zoom level (stroke-width="3")

Note that with stroke-width="3" there is noticeable freezing when either scrolling or trying to move on map on small zoom levels (here we are, not yet started and performance says hi:)).

As a quick resolution for the "stable" deck we might as well set stroke-width="1" and be done with it. As a future workaround - have default stroke-width="1", but set stroke-width="3" after certain zoom level (or even return to previously mentioned proportional border width control).

Edit: JSV library has event onViewportChange(scale, transX, transY) which makes it easy to control IM properties depending on the current zoom level.

Tell me what you think of it.

To reproduce:

  1. load AnkiWebView Inspector(31746032) add-on
  2. set strokeWidth in _ug-interactive_map_config.js to appropriate value
  3. start card review session
  4. open inspector by right click -> inspect
  5. open console
  6. execute statement document.querySelectorAll("svg [data-code]").forEach(x => x.setAttribute("vector-effect", "non-scaling-stroke")); to set the attribute
  7. close inspector

To summarize prioritization:

Regarding prioritisation, here is my personal opinion

Makes sense, assuming not everything needs to be in the first stable release.

  • Stable release
    • Zoom animation max level
    • Mobile media refreshing
    • Small-area regions interactability
    • Separate regions display (e.g. Scotland, England, Wales and Northern Ireland)
  • After-release incremental improvements
    • Everything else from my previous comment
  • Keep an eye on
    • Performance

@axelboc
Copy link
Collaborator

axelboc commented Aug 22, 2024

I like stroke-width="1" personally, even at high zoom levels. The stroke width is actually quite inconsistent in the static maps and I think it's for the same reason: they were probably generated without vector-effects="non-scaling-stroke".

@helitopia
Copy link
Collaborator Author

Hello,

Coming back with updates on the topic.

Small-area regions interactability

The item is resolved via:

  1. introduction of vector-effects="non-scaling-stroke" attribute option (see the commit) into each region element (JSV library)
  2. setting stroke-width="1" (UG codebase)
  3. changing maximum zoom level to 20000 - large enough to see the smallest region on map - Vatican City (UG codebase)

Mobile media refreshing

According to Anki docs and the discussion I initiated:

Anki will synchronize any sounds and images used by your notes. It will notice when media has been added or removed from your media folder, but will not notice if you have edited some existing files without adding or removing any. To get your edits noticed, you need to add or remove a file as well.

Media is synchronized when file addition/deletion/replacement happens and is not synchronized when files are simply edited. Apparently, manipulations performed by BrainBrew are classified as "editing" since the media sync is not triggered between imports of experimental deck with different script contents.

The solution to this issue is rather simple. With each release we may include a dummy non-empty* file having hashed name** (not starting with underscore). This will make sure that media sync is triggered while also allowing Anki to remove the dummy file on the next "Check Media" occasion (since the file does not start with underscore)

* - important as Anki recognizes only non-empty files during "Check Media"

** - in case a name is constant sync might not be triggered if a user did not "Check Media" since last UG import

It is important to note that any manual changes to configuration (or script logic) directly in media folder are thus not synchronized, so the decision to move customizable configuration into the note template was unconsciously the right one.

Zoom animation max level

To reiterate - the issue is that by default JSV will zoom in on correct region (back card side) up until maximum zoom level is reached or until the region fills either horizontal or vertical canvas space (see Iceland example in the comment above).

Due to "Small-area regions interactability" topic being resolved, we are setting maximum zoom level to extremely large value (to be able to zoom in on such region as Barbados). Thus, the problem is exacerbated leading to each region being zoomed up until it fills the canvas, thus providing very little context of the region's relative location:

As a neat solution I suggest:

  • have separate (from regular zoom max level) zoom animation max level

  • zoom animation max level is universal for all the regions

  • small regions are additionally highlighted with static-map-conforming red circle:

  • user is able to zoom and move on map in case additional context is needed (maybe have a configuration option to be able to disable the behavior)

In case we proceed with such solution, there is a need to determine:

  • universal zoom level
  • either region criteria for which red circle is displayed or manually full list of regions for which to display it (with its radius)
  • technically there will be required logic to calculate the center of the region that will be the center of the circle.

As another option to discuss - setting manually max zoom and max zoom animation levels for each region which will ensure that all of them are displayed correctly.

Attaching a link to the branch with recent changes in case you want to build a deck to play around and try to figuring out discussed items (changes on the branch are for testing purposes only yet). Note that zoom level is updated and displayed at the top for your convenience. Also note that displayed scale is 10% less actual one (e.g. setting zoomMax: 20 will maximum produce ~18 displayed zoom level)

Separate regions display (e.g. Scotland, England, Wales and Northern Ireland)

As I mentioned one of the solutions in my previous comment:

Probably the idea should be the same - Scotland, England, Wales and Northern Ireland are always split up (to avoid giving hints). When card requests selecting, for example, Scotland, you do so. In the other case when United Kingdom - you select either of the 4 regions and on the back side the whole country is highlighted

To summarize the idea:

United Kingdom case study:

  • England, Wales, Scotland and Northern Ireland are always displayed separately on front card side
  • If a card for United Kingdom is shown - selection of any of the 4 regions is considered correct. Back card side displays all 4 regions highlighted together (either with correct or wrong region color depending on the answer), creating illusion of the whole United Kingdom highlight*
  • If a card for Scotland is shown - normal flow of region selection. That is, selecting Scotland is considered correct and any other region - incorrect. Back card side highlight method is not any different from all other regions

* - if really necessary, additional option of back card side border removal between common regions might be investigated, making highlighted area appear as a whole (in this example - UK)

France and Corsica case study:

  • France (without Corsica) and Corsica are displayed separately on front card side
  • If a card for France is shown - selection any of the two regions is correct. Back card side highlights both regions with appropriate colors (creating illusion for the whole France)
  • If a card for Corsica is shown - only Corsica answer is considered correct (same as with Scotland for previous example).

Let me know what you think relating suggested solution (and, preferably, all other discussed items :)).

@aplaice
Copy link
Collaborator

aplaice commented Aug 31, 2024

Thanks very much for continuing to develop this!

Mobile media refreshing

CrowdAnki

Apparently, manipulations performed by BrainBrew are classified as "editing"

This is actually under the purview of CrowdAnki and is something that we could fix for all CrowdAnki users! :)

Anki apparently checks the mtime of the directory, when deciding what to do with media, when syncing:

https://github.com/ankitects/anki/blob/b7cb0c0d0081202586fd2d88541db962819736b3/rslib/src/sync/media/database/client/changetracker.rs#L59

(See also this commit where this behaviour was reintroduced:

ankitects/anki@35cbde6

)

The mtime of a directory is unchanged if you copy in a file that overwrites an existing one.

If you want to check this yourself, on a unix-like system:
# Use subdir for easier clean-up.
mkdir -p test_dir/subdir/
echo foo > test_dir/subdir/foo
stat -c %y test_dir/subdir/  # Get mtime 1
sleep 3  # or just wait manually
echo bar > test_dir/foo
cp test_dir/foo test_dir/subdir/foo
stat -c %y test_dir/subdir/  # Get mtime 2

The two mtimes for test_dir/subdir/ are the same despite test_dir/subdir/foo having been overwritten.

(In contrast, if you just add in a new file, and then remove it, the mtime of the dir does change (even though the actual contents of the dir hasn't changed compared to before adding the new file).)

CrowdAnki just uses shutil.copy for all the imported media files, so if there are no new files, the mtime is unchanged. This is why Anki doesn't sync the media changes, in our case. However, we could just make CrowdAnki "touch" the directory (e.g. with pathlib), on import. (The disadvantage is slightly slower sync (see the above Anki commit) after CrowdAnki imports, but CrowdAnki imports aren't usually that frequent, and IMO the change in "correctness" (expected behaviour of sync) is worth it.)

If you think it's a good idea, I'll open an issue for CrowdAnki to see if anyone complains and if nobody does, I'll implement the change. :)

Workaround

Otherwise, the workaround as described makes sense!


Small-area regions interactability

Thanks! These make sense! The countries become slightly "pointy" at high zoom levels, but as I understand that's a trade-off between performance+file size and detail of the map.

Zoom animation max level

zoom animation max level is universal for all the regions

Just to make sure: if I understand the name correctly, this would only be important for sufficiently small regions? (i.e. large regions would still be fully displayed if their desired zoom animation level is smaller than the max level.)

small regions are additionally highlighted with static-map-conforming red circle:

Yes, this would be lovely! :) I'm not sure whether we need this as an essential part of the next iteration, though!

(Even greater might be also having a zoom-box (i.e. a second, zoomed-in copy of the map, so that the user could both see the details of the country and the context, at a glance, without having to change zoom), but that's definitely for the very long-term, if at all.)

maybe have a configuration option to be able to disable the behavior

I'm not sure I understand this.

setting manually max zoom

Why would we need a per-country max zoom level? If the user really wants to zoom in a huge amount (e.g. to inspect a smaller, neighbouring country) then why not let them? (Is there a performance disadvantage to allowing a high zoom level? Or would it mainly be about preventing the user from zooming in to the levels where things start getting granular? (but we would still allow such high zoom levels for some other countries anyway.)

setting manually [...] max zoom animation levels

Yeah, that might be useful, but probably a lot of work (choosing levels for each country).

IMO we should just have a global (config-adjustable) max animation zoom level, for now, and let people play around with it, to see what is most convenient and whether different max levels for different countries would be useful in practice.

either region criteria for which red circle is displayed or manually full list of regions for which to display it (with its radius)

technically there will be required logic to calculate the center of the region that will be the center of the circle.

In principle, these could be stored in the note itself as (part of) a field. (e.g. as part of the region code field (say, SG (lat, lon) instead of just SG for Singapore (though it's ugly/hacky).) Having some "height"/"width" threshold for displaying the circle and calculating the centre of the region is AFAICT straightforward computationally — the main challenge with doing it "on-the-run" in the note/script/Anki itself might be conveniently/quickly accessing the "map" in _ug-world.js. (or it might not :))

(We could also have a look-up table somewhere in the _ug-... files.)


Separate regions display (e.g. Scotland, England, Wales and Northern Ireland)

I don't think this is great (in terms of the visuals — the "click workflow" itself is perfect), but I agree that it seems to be the best solution (I don't have any better ideas :().


In case you or somebody else has some other ideas, I'll try to describe the desiderata, as I see them (obviously, everybody please feel free to disagree!).

The overall behaviour of what happens when one clicks on a given region is (IMO) exactly what we want.

However, stylistically, there are two main stumbling points:

  1. borders
  2. hover highlight

For borders, we'd ideally have different kinds of borders (international borders, internal borders, disputed borders), which would (IMO) resolve the issue of having borders within some countries, but not others. AFAIU this would require significant changes to the JSV library, but at least I see a good (long-term) theoretical solution.

For hover-highlighting we would like to both:

  1. be consistent country-wise (hovering over any part of the country "highlights" the entire country), but also
  2. hint what are the "interactable" elements (i.e. hovering "highlights" the smallest "interactable" region)

which are clearly inconsistent with each other... I'd almost be in favour of just dropping hover-highlighting, but that would also be unfortunate.

I'm also worried about what we should do in cases like Serbia vs. Kosovo, Georgia vs. South Ossetia, Somalia vs. Somaliland or China vs. Taiwan. (Currently, in the interactive map, Kosovo and Taiwan are separate, while South Ossetia and Somaliland aren't, but I don't know what would be a generally correct approach here.)

Additionally, there's the future question of how to deal with disputed borders (e.g India/China/Pakistan in Kashmir), where I'm not even sure what the correct behaviour would be for the effect of clicking, but we can deal with that once we get to it :) (Edit: On second thought, the optimal click grading behaviour would probably just be accepting the disputed region as being part of all claimants.)


Thanks again for the comment and the changes to the JSV library/AUG itself (and sorry for the length!)!

@axelboc
Copy link
Collaborator

axelboc commented Sep 1, 2024

Thanks for investigating Anki's media folder update. Looks like there's a solution in sight!

Regarding the max zoom level, it would be ideal to find a programmatic solution in the library. I'll try to investigate if I find the time.

Regarding "multi-part" regions, I think what you suggest is good enough for now: highlight/select the smallest parts on the front card on hover/click; highlight all parts on the back card.

However, perhaps a long term solution would be to allow multiple selections on the front card? I'm thinking that users would first have to select one of the parts (e.g. Scotland) without any hints, then a counter would appear in the corner "1/4" hinting that there's more to select. If they select any wrong region, they fail right away; if they manage to select all regions without making any mistake, they succeed.

@aplaice
Copy link
Collaborator

aplaice commented Sep 2, 2024

However, perhaps a long term solution would be to allow multiple selections on the front card?

This is a very interesting idea, but it feels finicky and potentially annoying for the user (many clicks for a single card).

@helitopia
Copy link
Collaborator Author

Thank you for the feedback

@aplaice

Mobile media refreshing

This is actually under the purview of CrowdAnki and is something that we could fix for all CrowdAnki users! :)

Right, I meant CrowdAnki.

If you think it's a good idea, I'll open an issue for CrowdAnki to see if anyone complains and if nobody does, I'll implement the change. :)

It is definitely a better solution as the option with dummy file is basically a hack and would require to either manually create the file with every release or to write a bash script to do so automatically, which is obviously more work and no benefit to overall CrowdAnki community.

Small-area regions interactability

Thanks! These make sense! The countries become slightly "pointy" at high zoom levels, but as I understand that's a trade-off between performance+file size and detail of the map.

Yes, they did.

Although it is possible to make the map more detailed further (converting shape files to GeoJson and then SVG). Such map, assuming the current maximum zoom level is kept constant (20000), will create appearance of higher detail even on the smallest regions (i.e. Vatican will look like as if it has as many details as France). Of course, such improvement also increases map storage size, but certainly a balance can be found (+ only certain regions can be "detailized" in contrast to the whole map). Right now this item is low on the priority list.

Zoom animation max level

Just to make sure: if I understand the name correctly, this would only be important for sufficiently small regions? (i.e. large regions would still be fully displayed if their desired zoom animation level is smaller than the max level.)

There are 2 sides to the solution:

  • zoom animation max level - is universal and allows to see context when reviewing relatively large regions
    • For example, with 20000 zoom (not animation) max level we still see Germany across the whole canvas with very little context:

      while preferred zoom would be:

      Note that this part in no way helps to deal with relatively small regions (zoom animation max level too high - no context, too low - region is not visible)

  • red circle - applied to resolve the issue by creating an accent on relatively small regions (refer to the screenshot in the comment above)

I'm not sure whether we need this as an essential part of the next iteration, though!

It depends. If aforementioned solution with universal zoom animation level is chosen then the red circle is essential for highlighting relatively small regions.

maybe have a configuration option to be able to disable the behavior

I'm not sure I understand this.

I meant configuration option to enable / disable zooming and moving on back card side map to gain more context (e.g. Zoom in closer on Vatican). But, actually, never mind - now that I look at it again it seems like a useless functionality (to be able to enable / disable zooming and moving, currently it is always enabled).

Why would we need a per-country max zoom level?

Actually you are right - there is no sense in changing current max zoom level in any way. Only manual setting of zoom animation max level is relevant (e.g. lower for France, higher for Vatican so that when choosing region map animates to appropriate zoom level, predefined for each region).

IMO we should just have a global (config-adjustable) max animation zoom level, for now, and let people play around with it, to see what is most convenient and whether different max levels for different countries would be useful in practice.

Agree, though as I mentioned - having universal zoom animation max level will not resolve the issue of relatively small regions, invisible from it. So either red circle or overridden zoom animation max level for such regions is required.

In principle, these could be stored in the note itself as (part of) a field. (e.g. as part of the region code field (say, SG (lat, lon) instead of just SG for Singapore (though it's ugly/hacky).)

IMO this is the best option at the moment - write down center of circle for those regions that need it.

@axelboc

Regarding the max zoom level, it would be ideal to find a programmatic solution in the library

Which one do you mean? (i.e. red circle, zoom animation max level, both)

To summarize

  • Small-area regions interactability - ✔️

  • Mobile media refreshing - ⌛

  • Zoom animation max level - ⌛

    • Determine which of the solutions to apply (not limited to these two):
      • Universal zoom animation max level + red circle
      • Universal zoom animation max level(zaml) + zaml overriding (to the larger value) for relatively small regions
  • Separate regions display - ⌛

    • For now - highlight/select the smallest parts on the front card on hover/click; highlight all parts on the back card. @helitopia
    • Discuss future correction

aplaice added a commit to aplaice/CrowdAnki that referenced this issue Sep 15, 2024
Otherwise, if in the source CrowdAnki decks a file has only been
edited, this won't be synced to other devices.

By default, Anki only checks whether it should more expensively check
for changes to individual media files if the mtime of the entire media
directory has changed.

(According to the docs:

https://docs.ankiweb.net/syncing.html#media

> It will notice when media has been added, removed or replaced in
> your media folder, but will not notice if you have made edits to
> existing files.

However, the mechanism by which it checks for this is via the
directory is (currently!) via the mtime of the dir:

https://github.com/ankitects/anki/blob/b7cb0c0d0081202586fd2d88541db962819736b3/rslib/src/sync/media/database/client/changetracker.rs#L94

)

Note that this means that every time CrowdAnki imports a deck, with
media, Anki will have to perform the more expensive check.

The cost of this "second" check was deemed sufficiently high that the
current behaviour (of two checks) was (re-)introduced here:

ankitects/anki@35cbde6

However, given that importing CrowdAnki decks is not a frequent
occurrence (probably less frequent than adding new media files oneself
— which also triggers the "second" check), this is a worthwhile
change.

For background see here:

anki-geo/ultimate-geography#638 (comment)
aplaice added a commit to aplaice/CrowdAnki that referenced this issue Sep 15, 2024
Otherwise, if in the source CrowdAnki decks a file has only been
edited, this won't be synced to other devices.

By default, Anki only checks whether it should more expensively check
for changes to individual media files if the mtime of the entire media
directory has changed.

(According to the docs:

https://docs.ankiweb.net/syncing.html#media

> It will notice when media has been added, removed or replaced in
> your media folder, but will not notice if you have made edits to
> existing files.

However, the mechanism by which it checks for this is via the
directory is (currently!) via the mtime of the dir:

https://github.com/ankitects/anki/blob/b7cb0c0d0081202586fd2d88541db962819736b3/rslib/src/sync/media/database/client/changetracker.rs#L94

)

Note that this means that every time CrowdAnki imports a deck, with
media, Anki will have to perform the more expensive check.

The cost of this "second" check was deemed sufficiently high that the
current behaviour (of two checks) was (re-)introduced here:

ankitects/anki@35cbde6

However, given that importing CrowdAnki decks is not a frequent
occurrence (probably less frequent than adding new media files oneself
— which also triggers the "second" check), this is a worthwhile
change.

For background see here:

anki-geo/ultimate-geography#638 (comment)
@helitopia
Copy link
Collaborator Author

Keeping you updated.

Region separation (e.g., Corsica and France) turned out to be a burdensome task - needed to migrate to GeoJson map first and only then start isolating regions by their polygons (which is also slow due to it being mostly manual).

Hoping to show the results soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
structure Templates, tags, generated decks, etc.
Development

No branches or pull requests

4 participants