[general]
name=QuickMapCompare
qgisMinimumVersion=3.16
description=Build a grid of side-by-side viewports in a dockable panel to compare QGIS layers, built-in tile basemaps, and web map providers at once, with per-viewport live sync to the main map canvas.
version=1.1.1
author=Siddharth
email=siddharthgupta7may@gmail.com
category=Web
homepage=https://github.com/Siddh75/quick_map_compare
tracker=https://github.com/Siddh75/quick_map_compare/issues
repository=https://github.com/Siddh75/quick_map_compare
about=QuickMapCompare builds a grid of side-by-side "viewports" in a dockable panel, each showing a QGIS layer, a native WMS/XYZ tile basemap (OpenStreetMap, Esri, CartoDB, Google Maps, Bing Maps, and more), or an embedded Web Map Provider. Every viewport can live-sync to the main QGIS canvas as you pan and zoom, and layer/tile viewports support an on-canvas "Swipe Compare" gesture (hold S and drag) to compare directly against the live canvas with no separate window.
icon=icon.png
tags=maps,compare,side by side,swipe,google maps,wikimedia maps,openrailwaymap,opensnowmap,esri,hillshade,usgs,openstreetmap,cyclosm,cartodb,bing maps,wms,xyz,tiles,web,layers,dock,grid,viewport,sync
experimental=False
deprecated=False
changelog=1.1.1
        - The busy/spinner cursor added in 1.1.0 now also reappears when the armed tile reloads because the main canvas was panned or zoomed, not just on its very first load. Wheel-zooming in particular produces no mouse movement for the cursor to react to, so this is now driven directly by the tile's own loading state changing (plus the main canvas's own extent-changed signal as a catch-all), rather than only being re-checked on mouse move.
    1.1.0
        - Added a busy/spinner cursor over the main canvas while a tile armed for Swipe Compare is still loading its own content. Pressing S at that moment won't have much to show yet, so the cursor now makes that clear instead of pressing S looking like it silently did nothing. Clears automatically once the tile finishes loading, once a swipe actually starts, or once nothing is armed.
    1.0.3
        - Fixed a crash (QGIS quitting unexpectedly, usually within seconds of starting) introduced in 1.0.2. That version caught the S key application-wide via QApplication.instance().installEventFilter(), which is invoked for every event sent to every object in the whole application -- PyQt's binding layer has to identify the runtime type of each one to hand it to Python, and doing that for QGIS's huge, dynamically-loaded plugin/provider set turned out not to be safe on macOS, crashing QGIS outright, independent of whether Swipe Compare was even being used. Reverted to filtering only the main canvas and its viewport.
        - S not needing an extra click first is preserved, though: the canvas now grabs keyboard focus by itself as soon as the mouse hovers over it, so pressing S works immediately -- unless a text field elsewhere (a layer name, the expression builder, ...) is actively focused, in which case hovering the canvas leaves your typing alone.
    1.0.2
        - Fixed Swipe Compare's S key not always working when the mouse was pointed at another docked panel/viewport (or hadn't been re-clicked into the main canvas since a settings dialog or the dock's own swipe icon was last clicked). Superseded by 1.0.3 above (this version's fix caused a crash).
        - Fixed Swipe Compare occasionally getting stuck "on" with S no longer pressed.
    1.0.1
        - Fixed Swipe Compare sometimes needing a couple of S presses to actually engage. Every press was re-rendering the armed viewport's mirror from scratch (a blocking render + wait), and a quick tap's key-release could land before that finished, silently dropping the press. The rendered mirror is now cached and reused whenever nothing relevant (tile, style, viewport size, or main-canvas extent) has changed since the last press, so repeat presses with an unchanged view are instant and can no longer race the render.
    1.0.0
        - First stable release: marked no longer experimental. Shortened the plugin description; no other functional changes since 0.8.2.
    0.8.2
        - "Add Viewport" no longer forces the source picker when the panel already has viewports but was just closed (via its own titlebar close button, which only hides it) -- clicking the toolbar/menu action now simply reopens it as it was. The source picker still opens as before the very first time (no panel/viewports yet) or whenever the panel is already open.
    0.8.1
        - Fixed the native "Google Maps" WMS/XYZ tile not rendering: its tile URL contains literal "&" characters, which were corrupting the outer XYZ connection string QGIS uses internally, truncating the URL and losing the {x}/{y}/{z} tokens. The "&" is now percent-encoded before use.
        - Fixed Swipe Compare getting stuck "on" indefinitely (until S was pressed again) if S was pressed and released again quickly while the armed layer/basemap was still loading: the render used to wait for could take long enough for the key-release to be processed (and silently dropped) before swipe had actually started. The physical key state is now tracked independently and checked before arming.
        - Added a small "Loading…" indicator over a tile while its content is being fetched -- for layer/WMS-XYZ tiles this follows QGIS's own render job, and for Web Map Provider tiles it follows the embedded page load.
    0.8.0
        - Removed the Windy, RainViewer, Waymarked Trails (Hiking), OpenSeaMap, and OpenTopoMap web map providers -- none of them could be verified working reliably.
        - Renamed the "Map provider" source kind to "Web Map Providers" and "Basemap tile layer" to "WMS/XYZ tiles" throughout the UI.
        - Added a native "Google Maps" WMS/XYZ tile (Roadmap/Satellite/Terrain/Hybrid, switchable via the settings-gear icon) -- no API key, no webview chrome, independent of the existing webview "Google Maps" provider.
        - Added "CartoDB" (Light/Dark/Voyager), "Esri Ocean", "Esri NatGeo", "Esri Light Gray", and "Bing Maps (Aerial)" as new WMS/XYZ tile basemaps.
        - WMS/XYZ tiles with more than one style (Google Maps, CartoDB) now show a settings-gear icon to switch between them, same as multi-style web map providers already did.
    0.7.1
        - Removed the "Google Maps (JS)" provider and the "Stamen Terrain" basemap tile layer (and their associated API key settings/menu actions), since neither could be tested locally. Plain "Google Maps" (no API key needed) and the other basemap/provider options are unaffected.
    0.7.0
        - Added a vertical Swipe Compare mode: clicking a viewport's "Add to Swipe Compare" icon now cycles off -> horizontal (left/right, the original behavior) -> vertical (top/bottom, a new draggable horizontal divider) -> off, instead of a plain on/off toggle.
        - Fixed Swipe Compare showing the *previously* armed viewport the first time S is pressed after switching to a different one: QgsMapCanvas renders asynchronously in a background job, so grabbing immediately after refresh() could catch it before the new layer had actually finished rendering. Now waits for rendering to complete before grabbing.
    0.6.2
        - Fixed Swipe Compare always showing the picked viewport zoomed in: on a HiDPI/Retina screen, QWidget.grab() returns a pixmap whose raw pixel size is scaled by the display's device pixel ratio, but the swipe overlay was slicing it with a source rect sized in logical pixels -- sampling only a shrunk corner of the image, which looked like a zoomed-in crop. It now lets Qt draw the pixmap at its natural size (DPI-aware) and clips to the divider position instead of cropping the source.
    0.6.1
        - Fixed two Swipe Compare bugs: the divider didn't track mouse movement while S was held, and the two sides weren't pixel-aligned. Root cause of both: QgsMapCanvas is a QGraphicsView, whose actual mouse-event surface is its internal viewport() child, not the canvas widget itself -- the swipe overlay and its mirror rendering now use the viewport's own size/coordinate space (where key events still target the canvas, since that's where keyboard focus actually lives).
    0.6.0
        - Reworked Swipe Compare from a separate dialog into an on-canvas gesture: each layer/basemap viewport tile now has an "Add to Swipe Compare" icon in its overlay bar. Arm one, then hold S and move the mouse over the main QGIS canvas to swipe between the live canvas and that viewport, composited directly onto the canvas itself. Web map provider viewports don't offer the icon -- there's no reliable way to composite an external web page's rendering onto the live canvas at interactive speed, so rather than offer something flaky they're excluded.
    0.5.3
        - Fixed the viewport (right) side of Swipe Compare still rendering blank the second time the dialog opens: reusing the previous mirror widget across a hide/show cycle could leave it stuck showing stale/blank content (the WebView mirror in particular suspends its Chromium renderer while its window is hidden). Both mirror widgets are now rebuilt fresh every time the dialog is opened rather than reused.
    0.5.2
        - Fixed Swipe Compare rendering blank the second time it's opened: closing it via its window-close button doesn't destroy the dialog (the plugin caches and reuses the same instance), but its cleanup code was tearing down the mirror canvases as if it did. That cleanup now only runs once, when the plugin itself unloads.
    0.5.1
        - Fixed Swipe Compare misalignment: it previously grabbed snapshots of the already-existing main canvas and viewport tile (each a different size/aspect ratio) and independently stretched both to fit the dialog, which threw features out of alignment between the two sides. It now renders both sides from dedicated off-screen QgsMapCanvas/WebView "mirrors" resized to exactly match the swipe widget and driven from the same requested extent, so both sides are pixel-aligned with no extra scaling at composite time.
    0.5.0
        - Added "Swipe Compare...": a separate dialog (Plugins menu or toolbar) that composites the main QGIS canvas against any currently open viewport (layer, basemap, or web map provider), split by a divider you click-and-drag directly on the image.
    0.4.2
        - Refactored: moved all map-source logic (provider/basemap definitions, URL builders, the XYZ tile basemap layer builder, API key storage, and coordinate/zoom helpers) out of quick_map_compare.py into a new sources.py module. No behavior change.
    0.4.1
        - Moved CyclOSM from a webview provider to a native XYZ basemap tile layer: cyclosm.org's own demo site pops up a recurring "About" modal on every load, which reappeared on every sync since that's a page reload. CyclOSM's public tile service (tile-cyclosm.openstreetmap.fr) sidesteps that entirely.
        - Added OpenStreetMap back as a native XYZ basemap tile layer (tile.openstreetmap.org) rather than the previously-removed webview provider, for the same reason -- no page/site chrome to pop up.
    0.4.0
        - Added a "Basemap tile layer" viewport source: built-in XYZ terrain basemaps (Esri World Hillshade, Esri World Topographic, USGS Topo, Stamen Terrain) rendered natively via QgsMapCanvas, same pixel-perfect sync as QGIS-layer viewports, no webview/GPU crash risk. Stamen Terrain needs a Stadia Maps API key, set via Plugins > QuickMapCompare > Set Stadia Maps API Key.
        - Added specialized OSM-family map providers: OpenSeaMap, OpenRailwayMap (with Standard/Max Speed/Signals/Electrification styles), OpenSnowMap, CyclOSM, and Waymarked Trails (Hiking).
        - Added weather map providers: RainViewer and Windy (with Wind/Rain/Temperature/Clouds/Pressure overlay choices) -- both work with no API key.
    0.3.1
        - Removed OpenStreetMap as a viewport provider.
    0.3.0
        - Added a "Google Maps (JS)" provider that drives the Google Maps JavaScript API directly with all UI chrome disabled, instead of embedding the ordinary maps.google.com page -- avoids the search bar, sign-in prompt, and "Heavy traffic" popups the URL-embedded Google Maps provider shows, which can't be suppressed since that one is just a normal page load. Requires a Google Maps JavaScript API key, set via Plugins > QuickMapCompare > Set Google Maps API Key.
    0.2.0
        - Floating, semi-transparent overlay topbar per tile (Sync / Change source / Style settings at top-left, Close at top-right) instead of a fixed header row.
        - Mouse-cursor crosshair in every viewport, pixel-perfect for layer tiles and web-mercator-based for provider tiles.
        - Resizable viewports: tiles now live in nested QSplitters instead of a fixed grid, so dividers can be dragged.
        - Per-tile style settings moved into a small dialog opened from a settings (gear) icon, shown only for providers with more than one basemap/overlay choice.
    0.1.0
        - Initial release: dockable comparison panel, grid of viewports (QGIS layers or web map providers), per-viewport Sync toggle, per-provider-tile basemap/overlay style pickers, adaptive grid reflow as tiles are added/removed.
