javalent / obsidian-leaflet

Adds interactive maps to Obsidian.md using Leaflet.js
512 stars 30 forks source link

Image Map Specification Logic #278

Closed Servinjesus1 closed 1 year ago

Servinjesus1 commented 2 years ago

I'm confused by the logic for fully specifying an image map. I get this plugin was made with real maps in mind, but the latitude/longitude logic seems to not play well with images.

Here's my MWE (MVP? my template, so to speak) for an image map:

id: image-map
image: image.svg
bounds: # Staple image to canvas
    - [ 0, 0 ]
    - [ 100, 100 ]

# Set Zoom bounds (needs stapling above)
minZoom: 3
maxZoom: 7
defaultZoom: 1

# Set coordinate system
unit: feet
scale: 1
lat: 50%
long: 50%

# Additional Features
darkMode: true

So, I'm curious:

  1. Where should (0,0) be? At the bottom left corner of the image?
  2. What do the bounds specify, particularly in relation to the coordinates (or "canvas")? I know they're % from top-left corner (no % though), and if not as above, they should skew the image. Should this skew work with svgs?
  3. Why no % in bounds but needed in lat/long (c.f. #138 )?
  4. Why is enforcing bounds required (e.g. #272)? It's currently necessary for Zoom to work correctly. Might I suggest making the image size in pixels (or for svgs the "nominal size" in pixels) the default value for bounds and making the Zoom and scale parameters play well with this (so scale is in units of unit/pixel rather than unit/image-size, and maybe Zoom is in units of pixels/leaflet-size)? I think then images would feel a lot more like "maps" (or engineering drawings, if you're familiar with those), when necessary, and also like a basic image if not.

I just tried to make an image map with this svg specifically, and the origin looks like it's way below the bottom left corner of the image, which spurred my questions above.

valentine195 commented 2 years ago

I actually did make the plugin for images first, but feedback for real-world usage has driven a lot of the development.

Some of these issues have come up because I was inconsistent in my development and some of these issues are just because of the way the underlying LeafletJS module works.

  1. Lat/Long of image maps is from the top left corner.

  2. Bounds are specifically setting this LeafletJS parameter. When you create an image map, you are actually creating an ImageOverlay on a "Simple" CRS that map lat/long to x/y directly. Unfortunately, the way that Leaflet deals with ImageOverlays means that I have to do a little bit of work to ensure the image layer works, which is based on the width and height of the image and the zoom level specified.

The bounds parameter allows you to explicitly set the bounding box of the image, which means coordinates are exactly what you expect them to be. They aren't actually a percentage anything. You can make them whatever you want, and the map coordinates will update accordingly. It is recommended to find some measurement system on the map to determine a pixel/mile (or whatever) ratio, and set your bounds that way.

  1. I set lat/long to percentage because there isn't a way to determine the resulting coordinate system your image will receive. In setting bounds you are setting the coordinate system you want the map to have.

  2. I believe this is a result of the image maps being ImageOverlays and not true TileLayers (aka just the way leaflet works for these). Setting bounds locks the overlay in place.

I'll have to look more into the issue you had with the SVG as I have time, sorry about that!