=== PeakMaps ===
Contributors: consigno
Tags: maps, leaflet, hiking, gpx, peaks
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.12.0
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html

Leaflet map with GPX tracks, markers, elevation profile, and its own filterable peak database with table and Gutenberg blocks.

== Description ==

Turn your list of summits, trails, and viewpoints into a beautiful, interactive map — no coding required.

PeakMaps is a WordPress plugin built for hiking blogs, outdoor clubs, tourism sites, and anyone who wants to showcase peaks, trails, and points of interest on a real, interactive map. Add a searchable database of locations, complete with GPX tracks and elevation profiles — then drop it into any page or post with a Gutenberg block or shortcode.

PeakMaps is **completely free**, with no peak-count cap, no expiring features, and no upgrade popups. **PeakMaps Pro** is a separate, optional add-on for sites that want Norwegian topographic maps (Kartverket), custom marker styles, extra data fields, on-map tools, GPX downloads, and bulk CSV import/export.

[See it in action: demo table](https://fjellturblogg.no/fjelltopper) | [demo map](https://fjellturblogg.no/kart)

= What PeakMaps does =

Add peaks to your own dedicated database, attach GPX tracks, and PeakMaps takes care of the rest: rendering them on interactive Leaflet maps, generating a sortable and filterable table, calculating elevation profiles — all without a single line of code. Place as many maps and tables as you like, anywhere on your site, each with its own filters and settings.

= 🗺️ Interactive map =

* Built on **Leaflet** — fast, lightweight, and mobile-friendly.
* **Marker clustering** keeps busy maps clean at lower zoom levels.
* Background layers: **OpenStreetMap** and **OpenTopoMap**, with an easy switcher for visitors.
* **Fullscreen mode** for an immersive map view.
* Smooth touch and pinch-zoom on mobile.

= 🏔️ GPX tracks and elevation profiles =

* Attach a GPX track to any peak and it renders on the map automatically — the map zooms to show the whole track.
* The peaks the track passes are marked in the elevation profile, with their names.
* A map button colours the track by steepness, like the elevation profile.
* Map and profile work together: point at the track on the map to see that spot in the elevation profile, or click the profile to zoom the map there.
* Optional **distance markers and direction arrows** along the track, switched on and off by visitors with a «km» button on the map.
* **Elevation profile charts** with interactive hover tooltips — elevation and distance at any point along the track.
* Ascent/descent totals, min/max elevation, total distance calculated automatically, plus an optional **estimated walking time**.
* Optionally **coloured by steepness** (0–5 % up to 35 %+), with the gradient in the hover tooltip; **start and finish** are marked on the map.
* **Secure GPX proxy** built in — tracks hosted anywhere load smoothly without CORS issues.
* Each track's **length and total ascent are stored with the peak**, and the admin warns you when a GPX file can't be read or never comes near its peak (usually the wrong file).

= 📊 Smart, filterable table =

* Fully **sortable and searchable** — sort by name, elevation, track length, ascent, municipality, county, visited date, and more.
* **Live filtering** by municipality, county, elevation range, track length (e.g. hikes under 10 km), free-text search, and visited status — no page reload.
* **Pagination** with configurable results per page.
* Optional row-number column and configurable column selection per instance.

= 🗄️ Your own peak database =

* A dedicated, purpose-built database — not repurposed WordPress posts — for fast, clean querying at any scale, with no upper limit.
* **Visited/completed tracking** — doubles as a personal or club peak-bagging log.
* Show/hide individual peaks without deleting their data.
* Full admin interface: search, filter, sort, bulk-edit, bulk-delete, and duplicate entries.

= 🌍 Built for real-world use =

* Works via **Gutenberg blocks** (with live editor preview) or classic **shortcodes** (`[peakmaps_map]` and `[peakmaps_table]`).
* **Norwegian Bokmål translation** included; standard WordPress i18n for adding more languages.
* Automatic **cache clearing** on settings changes, compatible with WP Rocket, W3 Total Cache, WP Super Cache, LiteSpeed Cache, and WP-Optimize.
* Assets load only on pages that actually contain a map or table.

= PeakMaps Pro =

[PeakMaps Pro](https://consigno.no/peakmaps) is a separate, optional add-on that extends the free plugin without removing anything from it. Pro adds:

**🇳🇴 Norwegian Kartverket maps**
Norway's official topographic map, raster map, and nautical chart as additional background layers. When a Kartverket layer is active, Pro also refines elevation profiles against Kartverket's own terrain model for extra accuracy.

**🎨 Custom marker styles**
Choose from circular, square, triangular, diamond, or star markers in any colour — or upload your own custom marker image.

**📝 Five custom extra fields**
Add up to five fields with labels you choose — difficulty, parking notes, permit info, or anything your project needs. Supports wildcards (`*`, `?`), exclusion (`!`), and numeric comparisons (`>`, `<`, `>=`, `<=`) in filters.

**🛠️ On-map tools**
A distance-measuring tool and a «find my position» GPS button for visitors browsing on mobile.

**⬇️ GPX download**
Let visitors download GPX files, with an optional terms/consent dialog.

**📥 CSV import and export**
Bulk-load or update peaks from a spreadsheet, with insert mode (add new entries) and update mode (fill in missing fields on existing ones). Export your full peak database to CSV at any time — perfect for backups or editing in Excel.

[Find out more about PeakMaps Pro →](https://consigno.no/peakmaps)

= Perfect for =

* Hiking and outdoor blogs documenting summits, trails, and viewpoints
* Tourism boards and destination sites showcasing regional attractions
* Hiking clubs maintaining a shared, browsable peak list
* Personal peak-bagging logs for trackers working through a summit list

== Source Code ==

This plugin's own frontend script, `assets/js/nu_script.js`, is shipped as a whitespace-minified build for faster loading. Its full human-readable source — same code, same behavior, just formatted — is included in this plugin at `assets/src/nu_script.js`. No bundler, transpiler, or other build step is used beyond whitespace minification; regenerating the minified file from the source is a single pass through any standard JS minifier.

All other JavaScript and CSS files written for this plugin (everything under `assets/js/` and `assets/css/` not listed below) are already shipped in their normal, unminified, human-readable form — no separate source is needed for those.

Bundled third-party libraries (Leaflet, Leaflet.markercluster, Leaflet.fullscreen, Leaflet.UTM) are minified as distributed upstream; each file includes a header comment with its name, license, and source repository URL. GPXParser.js (MIT) is included in readable form with a few PeakMaps fixes, listed in its header comment.

== External services ==

PeakMaps connects to the following services. Nothing is sent to any of them unless a map is shown, or a peak with a GPX link is saved or recalculated.

**Map tiles — requested by the visitor's browser when a map is shown**

The browser asks the tile provider of the background map in use for the image tiles of the area in view. Each request carries only what any image request carries: the tile coordinates and zoom level, plus the browser's normal request data (IP address, user agent). No peak data, site content or personal data is sent.

* **OpenTopoMap** — the default background map, a topographic map built on OpenStreetMap data. Tiles from `tile.opentopomap.org`. [Usage policy](https://opentopomap.org/about) · [OpenStreetMap privacy policy](https://wiki.osmfoundation.org/wiki/Privacy_Policy) (OpenTopoMap does not publish a separate one)
* **OpenStreetMap** — the second background map in the layer switcher. Tiles from `tile.openstreetmap.org`. [Tile usage policy](https://operations.osmfoundation.org/policies/tiles/) · [Privacy policy](https://wiki.osmfoundation.org/wiki/Privacy_Policy)
* **Esri** (satellite, topographic) and **CARTO** (light, dark) — part of the plugin's layer list, but only shown when an add-on such as PeakMaps Pro switches them on. Tiles from `server.arcgisonline.com` and `basemaps.cartocdn.com`. Esri: [Terms of use](https://www.esri.com/en-us/legal/terms/full-master-agreement) · [Privacy policy](https://www.esri.com/en-us/privacy/overview). CARTO: [Terms of use](https://carto.com/legal/) · [Privacy policy](https://carto.com/privacy/)

**GPX files — requested by this site's server**

* *For the map:* GPX files hosted on another site are fetched through this site's own proxy, so the browser can draw them. The proxy only fetches URLs that exactly match a GPX link saved on a peak in this site's database.
* *For track statistics:* when a peak is saved, imported or recalculated, the server reads its GPX file (and the detailed «F» variant next to it, if there is one) to work out length, ascent, steepness and distance above 1000 m. A file on this site is read straight from disk; a file elsewhere is requested from the address given in the peak's GPX link.

Which third party, if any, receives a GPX request depends only on where the site owner hosts the files; the plugin's author runs no server involved in any of this.

== Installation ==

1. Upload the `peakmaps` folder to `/wp-content/plugins/`, or install the ZIP via Plugins > Add New > Upload Plugin.
2. Activate the plugin from the Plugins menu in WordPress.
3. Go to PeakMaps in the admin menu to set up map defaults and add peaks.
4. Add a map or table with the "PeakMaps" Gutenberg blocks, or the shortcodes `[peakmaps_map]` / `[peakmaps_table]`.

== Frequently Asked Questions ==

= How do I add peaks? =
Use the "New peak" button under the PeakMaps menu to add peaks one at a time — name, position, GPX track, and the other details.

= How do I display the map or table? =
Use the Gutenberg blocks, or the shortcodes `[peakmaps_map]` and `[peakmaps_table]`. Parameters are documented on the Help page in admin.

= The plugin uses a caching plugin — why don't my changes show up? =
The page cache may serve old HTML. PeakMaps clears the cache automatically when you save the map settings, but also remember to hard-refresh your browser.

= Do I have to pay to use PeakMaps? =
No. PeakMaps is completely free, with no locked features, limits, or license requirements.

== Screenshots ==

1. Interactive map with markers and elevation profile.
2. Sortable and filterable peak table.
3. Admin: map settings.

== Changelog ==

= 2.12.0 =
* Steepness on the track is now a button among the map's controls on the left: visitors switch the colouring on and off themselves, and their choice is remembered in the browser. The setting ("Steepness button" under Settings → Map → On the map) decides whether maps have the button; the track starts in its normal colour.

= 2.11.1 =
* PeakMaps' own scripts and styles keep their version number in the link (`?ver=`), also on sites where a speed plugin or the host removes query strings from static files. Without it, browsers kept the old map script after an update, and new map features did not show until the cache ran out.

= 2.11.0 =
* The track on the map can be coloured by steepness, in the same six gradient classes as the elevation profile (green 0–5 % to dark red 35 %+), with a small legend in the map's corner. For the map's own track (and every track of a hike map); worked out like the profile, and from the profile's own points when there is one. Off by default — "Steepness" under Settings → Map → On the map.

= 2.10.0 =
* The elevation profile marks the peaks the track passes: a ▲ on the line and the peak's name above it (names that would overlap go up a row; hovering at a ▲ names the peak too). Every peak on the map within 150 m of the track counts; peaks without a marker do not. On by default — "Peaks" under Settings → Below the map.

= 2.9.99 =
* Hike maps over several days: a map with `view` counts as a hike map with up to seven GPX tracks (a week, a track per day) instead of four — every peak shown on its own and all tracks shown from the start.

= 2.9.98 =
* Sorting: peaks without a value (no track) now come last in both directions also for steepness and for numeric columns added by an add-on (PeakMaps Pro sorts the peaks list by steepness, walking time and difficulty grade).

= 2.9.97 =
* The estimated walking time under the elevation profile follows a walking-time rule an add-on sets in the map settings (`walk_kmh`, `walk_climb_m` — PeakMaps Pro's difficulty limits); 5 km/h plus 1 hour per 600 m of ascent as before otherwise.

= 2.9.96 =
* A GPX file on this site that is replaced by a new file with the same name — or gets a detailed «F» file next to it, or loses one — is now noticed by its size and time when the peaks list is opened, and the length, ascent and steepness of its peaks are worked out again automatically. Before, that needed the "Recalculate length and ascent" bulk action, which is still there for GPX files on other sites. (New column `gpx_file_sig`; existing peaks just get their file recorded, with no recalculation of everything at once.)

= 2.9.95 =
* The add-on hook for the elevation profile's highest point (`peakmapsProElevSummit`) also gets every peak on the map with its registered height and position, so on a hike over several peaks the right summit can be chosen (PeakMaps Pro: the highest one the track passes, not the centre peak).

= 2.9.94 =
* Hike maps over several days: a map with `view` and up to four GPX tracks (a track per day) now counts as a hike map too — every peak shown on its own, all tracks shown from the start, and the map zoomed to show them all. Before, the tracks stayed hidden while their peaks sat in a cluster.
* Fixed: the hike-map setting from 2.9.93 was reset right after the map was set up, so it only partly worked.

= 2.9.93 =
* A hike map — one GPX track, with the peaks chosen for it (`view`) or only a few peaks — shows every peak on its own from the start instead of gathering them in a cluster that had to be clicked open. The cluster button still gathers them. Overview maps cluster as before.
* The map shortcode marks maps with `view` (`data-view`), so add-ons can tell a hike map from an overview map.

= 2.9.92 =
* Peaks list on phones: the ID column no longer breaks the ID letter by letter, which stacked the text down the cell and made every row tall.

= 2.9.91 =
* A map with several peaks but a single GPX track now treats that track as the map's own, also when it belongs to another of the peaks than the centre peak (loc), or the map has no centre peak: it loads straight away and gets the elevation profile, start and finish — before, it only loaded when its peak was clicked, and the profile never showed.

= 2.9.90 =
* The settings page is divided into tabs — General, Map, Background maps and Below the map — instead of one long page. All tabs are saved together, the page comes back on the same tab after saving, and a "Settings saved" notice now shows. Add-ons can add their own tabs (`peakmaps_settings_tabs` filter, `peakmaps_settings_tab_{id}` action); sections from older add-ons appear on a "More" tab.
* The elevation graph colour moved to "Below the map", next to the elevation profile.
* Shortcode help: the settings overview describes the tabs.
