| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
docs: add MkDocs website and live demo via GitHub Pages (#23) * docs: add MkDocs website and live demo via GitHub Pages Adds a Material for MkDocs documentation site, GitHub Pages workflow, and a hosted web build of the desktop app so the project has a public landing page, docs, and an interactive demo. The Vite base path is now configurable so the demo can be served from a subpath. * chore: update MkDocs and GitHub Actions dependencies Removed custom mermaid fence configuration in MkDocs and updated GitHub Actions to use the latest versions of upload-pages-artifact and deploy-pages actions. * Address Copilot review feedback - docs/plugin-api.md: prefix built-in plugin IDs with `maplibre-gl-` to match the IDs actually exported by @geolibre/plugins, so the activate() examples work. - mkdocs.yml: restore the superfences mermaid custom fence so architecture diagrams render via Material's built-in Mermaid runtime instead of as raw code blocks. - .pre-commit-config.yaml: run check-yaml with --unsafe so it tolerates the mkdocs !!python/name tag, which is what blocked the fence config before. | 4 个月前 | |
docs: add a Video Tutorials page (#2107) * docs: add a Video Tutorials page Adds docs/tutorials/videos.md, covering all six videos in the GeoLibre YouTube playlist with an embed, a summary, links to the related guide pages, and a collapsible chapter list for each. Wires it into the Tutorials nav and refreshes the four existing short video lists (README, Demos, Getting Started, Tutorials overview), which had drifted to three of the six, so they list every video and point at the new page. The first video's own description carries chapter timestamps that run past its 40:18 runtime, so that entry lists the topics without times rather than publishing timestamps that do not exist. * docs: order the video tutorials oldest first | 2 个月前 | |
feat(embed): let a layout=viewer embed opt into drawing (#3154) * feat(embed): let a layout=viewer embed opt into drawing `layout=viewer` deactivates the geometry editor, so a host page that embeds the read-only viewer cannot let the user draw, even though getDrawnFeatures and featuresChanged (#3021) can read a drawing back. Add a `draw` URL flag. With `?layout=viewer&draw` the geometry editor is let through (`isViewerBlockedPlugin`), so `?plugin=geo-editor` or a project that lists it can open its toolbar. Annotations and GeoAgent stay blocked. The flag only takes effect when the deployment grants `project:edit`, and without it nothing changes. `draw` is reserved so it never becomes a tool parameter in a `?tool=` link. The viewer also stops offering ways to edit or move data around the deployment's capability gates: Identify no longer shows Edit geometry or Edit attributes (this was already reachable in `layout=viewer` before this change), and the editor toolbar drops its Open/Save file buttons. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(embed): set viewer file-tools flag during render, document drawing readback needs The geometry editor reads its file-tools flag once at construction, and the plugin restore and ?plugin= deep link construct it from effects. Setting the flag from an effect in the guard hook could lose that race against a child's effect, so set it while rendering, which precedes every effect. Add a render test for it and record why an empty fileModes list is safe upstream. Docs: reading drawings back needs the embed allowlist and the export:data capability, not only project:edit; use a self-hosted placeholder URL in the drawing example. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * Address review feedback - Move the viewer gate on Identify's edit actions into useIdentifyEditActions and pass usePluginDeepLink the layout options instead of two booleans, so DesktopShell.tsx stays within the untested-module growth allowance (it had reached 1341 lines against a 1334 cap once merged with main), which failed Build and test. - Note in useViewerPluginGuard that layoutOptions.viewer comes from the launch URL and is fixed for the page's lifetime, so the render-time file-tools flag can never go stale and needs no reset on unmount. --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-authored-by: giswqs <giswqs@gmail.com> | 8 天前 | |
fix(i18n): use sentence case for English menu labels and headings (#3243) * fix(i18n): use sentence case for English menu labels and headings Menu items, buttons, dialog titles and headings in en.json mixed Title Case and sentence case. Switch the Title Case labels to sentence case, keeping proper nouns (products, services, standards, places), acronyms, and names of other UI surfaces ("the Layers panel") capitalized. Processing tool names are left alone: they come from the tool registries through the generated processing.toolMeta keys, and the matching toolbar.*Tool menus mirror them. Projection and CRS preset names are proper names and stay as they are. Also: - update the English fallbacks next to catalog keys, three hard-coded Add Data panel titles, and the plugin reference menu paths - regenerate docs/user-guide/plugins.md - update e2e selectors and unit-test expectations - lower the same strings where another locale copied the English verbatim (German is left alone: it capitalizes nouns) - document the casing and ellipsis conventions in docs/i18n.md Fixes #3231 * fix(i18n): match the Layers header collapse label to the rail's The left rail reads "Collapse Layers" (Collapse {{title}} with the panel name), so the Layers header button now says the same instead of "Collapse layers". * Address Claude review feedback - Match the vantor.openPanel aria-label and title fallbacks in the Vantor panel to the sentence-case catalog value ("Open Vantor STAC explorer"). * Address Claude review feedback - Update English strings that quote a renamed label or menu path to the new sentence-case names ("Download offline area", "Add comment", Settings → Environment variables, Project → Export → Export layers, Add data → LiDAR layer, and others), including the matching code fallbacks and hard-coded hints. - Keep "Open in Processing…": Processing is the toolbar menu's name, so it keeps its capital under the new style rule. * Address Claude review feedback - Match the share.role and share.expiry fallbacks in the Share dialog to en.json ("Access role", "Link expiry"). A sweep of every key/fallback pair found no other case-only mismatch. | 1 天前 | |
docs: add MkDocs website and live demo via GitHub Pages (#23) * docs: add MkDocs website and live demo via GitHub Pages Adds a Material for MkDocs documentation site, GitHub Pages workflow, and a hosted web build of the desktop app so the project has a public landing page, docs, and an interactive demo. The Vite base path is now configurable so the demo can be served from a subpath. * chore: update MkDocs and GitHub Actions dependencies Removed custom mermaid fence configuration in MkDocs and updated GitHub Actions to use the latest versions of upload-pages-artifact and deploy-pages actions. * Address Copilot review feedback - docs/plugin-api.md: prefix built-in plugin IDs with `maplibre-gl-` to match the IDs actually exported by @geolibre/plugins, so the activate() examples work. - mkdocs.yml: restore the superfences mermaid custom fence so architecture diagrams render via Material's built-in Mermaid runtime instead of as raw code blocks. - .pre-commit-config.yaml: run check-yaml with --unsafe so it tolerates the mkdocs !!python/name tag, which is what blocked the fence config before. | 4 个月前 | |
Add an AI disclaimer to the README and acknowledgements (#3173) Say that GeoLibre is primarily built with Claude Opus 5.5, under human direction and review. | 7 天前 | |
feat(python): drive the open desktop map from geolibre-mcp (#2829) * feat(python): let geolibre-mcp drive the open desktop map File tools still write a project on disk. The new live tools call the Notebook relay Desktop already runs, so an MCP client can move the map the user is looking at. Co-authored-by: Cursor <cursoragent@cursor.com> * Address review feedback - Bypass environment proxies when talking to the loopback relay, so HTTP_PROXY cannot carry the relay token off the machine (CodeRabbit). - Reject live_set_opacity values outside [0, 1] instead of reporting a value the app clamps (CodeRabbit). - Probe pid liveness with OpenProcess/GetExitCodeProcess on Windows, where os.kill(pid, 0) sends CTRL_C_EVENT instead (Claude review). - Drop the unreachable https default port in Relay (Claude review). - Drop the no-op LiveError re-raise in require() (Claude review). * Address CodeRabbit review feedback - Check Windows pid liveness by waiting on a SYNCHRONIZE handle, so a process that exited with code 259 is not mistaken for STILL_ACTIVE. --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: giswqs <giswqs@gmail.com> | 25 天前 | |
feat(postgis): render PostGIS vector tiles natively on Android/iOS (#3172) * feat(postgis): render PostGIS vector tiles natively on Android/iOS The mobile apps cannot run the Martin tile server, so Add Data > PostgreSQL was hidden there (GeoLibre#2091). Render the tiles in-process instead: the Tauri backend connects to PostgreSQL directly (tokio-postgres + deadpool, rustls/ring) and builds each tile with ST_AsMVT, and MapLibre reaches it through a geolibre-pgtiles:// protocol. No process is spawned and no port is bound. - Tile URLs persist only the password-masked connection label; the protocol resolves it from this session's connects or the saved connections, so a reopened project's layers work without credentials in the project file. - The tile envelope is clipped to the table's extent before it is transformed, so projected CRSs (e.g. UTM) still render at low zoom. - SRID-0 columns use the rows' own SRID when they carry one, else the default SRID field. - sslmode follows libpq: prefer/require encrypt without verifying, and verify-ca/verify-full check against the webpki roots. - Mobile Tauri gets a tiles-only PostgreSQL form; desktop keeps Martin and the editable mode unchanged, and mobile browsers still hide the source. Tested on an Android phone (Redmi Note 9 Pro) against PostGIS 3.6.1 with EPSG:4326, 32748 and 54004 tables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address review findings on native PostGIS tiles Backend (postgis_tiles.rs): - Connect outside the global pool lock: one OnceCell slot per connection, so a slow host no longer stalls tiles from other databases and parallel first tiles share one connect. - Key pools by connection only; the default SRID moves into the plan key, so layers with different default SRIDs stop closing each other's pool. - SET statement_timeout in a post-create hook instead of the `options` startup parameter, which PgBouncer and hosted poolers reject. - Build each tile plan once per key (no stampede on first draw); a plan built without its extent clip is retried after 60 s, not cached forever. - source_info reuses the plan, and a failed extent yields bounds: None instead of failing the add. - Evict the least recently used pool, not the oldest. - Parse sslmode/sslrootcert like libpq (URI and quoted key/value forms), support sslrootcert PEM files, and implement verify-ca as chain-only. Frontend: - Mask password/sslpassword query parameters in connection labels so they never reach persisted tile URLs. - Queue tile requests per connection and drop ones MapLibre aborts. - Close a database's pool when its last layer is removed or the Add Data form closes unused; a replaced session connection is disconnected. - Note the certificate behaviour in the mobile notice and docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address code review of native PostGIS tiles Backend: - Evict only after a new connection succeeds, so a mistyped string never costs a pool that live layers use; slots still connecting don't count. - Never close a pool explicitly: eviction and disconnect drop the map's reference, and connections close when the last in-flight request ends. That stops in-flight tiles failing and covers a disconnect mid-connect. - One PostgisTileSourceRequest replaces the five loose command arguments and the repeated SourceKey construction; use f64::clamp. Frontend: - The Add Data form releases every pool it opened and no layer uses when it moves to another database or closes, not just the last one. - Shared helpers: savedPostgresConnectionsWithLabel, the POSTGIS_TILES_SOURCE_KIND constant, and a PostgresConnectionFields component used by both the Martin and the mobile forms. - MAX_TILES_IN_FLIGHT moves next to the URL helpers, and a test keeps it equal to the Rust POOL_SIZE (documented in docs/maintenance.md). i18n: - The reworded web notice gets a new key (webUnavailableNotice); the stale addData.postgres.desktopOnlyNotice is removed from every catalog so non-English users fall back to the correct English text. - New keys for the read-only table picker (tileSourceTable) and the unresolved-connection tile error, now thrown through i18next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address second CodeRabbit review of native PostGIS tiles - Keep serving an unclipped tile plan while one background task retries its extent, and double the retry wait after each failure (up to 1 h), so a slow or failing extent scan no longer stalls the layer's tiles. - Parse geolibre-pgtiles:// tile URLs by hand: Chromium and Android WebView before 130 read non-special schemes as an opaque path with no host, so every tile failed to parse there. - Mask connection labels with the regex path when the URL parser finds no host, so those WebViews no longer leave the userinfo password in the persisted label. - Docs: sslmode=prefer can fall back to plaintext; require, verify-ca or verify-full make encryption mandatory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): single plan rebuild guard and bounded password mask - PlanRetry tracks an in-flight rebuild, released by a drop guard however the task ends, so a rebuild that outlasts its retry delay can no longer be joined by a second one. - The userinfo password regex stops at `/`, `?` and `#`, so a port followed by an `@` in the query (`host:5432/db?application_name=a@b`) is no longer masked as a password and the label keeps its port and database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 6 天前 | |
Apply contingent values to related records and nonhosted services (#3206) * Apply contingent values to related records and nonhosted services Related tables now load their own contingent values with their metadata, so related-row inserts and updates are checked against them with the relationship's parent key in place, and the Related records form lists fitting values first, marks a broken restrictive group and disables Save until it is corrected. Nonhosted ArcGIS Enterprise services do not advertise contingent values on the layer. For editable layers, GeoLibre now asks the service for the layer's data element (queryDataElements) and reads its field groups' combinations from queryContingentValues, decoded the way Esri's JavaScript SDK reads that format (one shared string dictionary, {minValue, maxValue} ranges, per-subtype codes). A service that cannot describe its data elements is treated as having none. Part of #3180 * Address review feedback - Type the mutated Enterprise fixture in the subtype test, which broke the test type-check ratchet. - Key related-record notices by position and text, so identical notices cannot collide. - Remember, per layer, that a nonhosted service has no contingent values, so refreshes stop asking it again; saves still ask every time. * Address CodeRabbit review feedback - Remember only a confirmed absence of contingent values (the service cannot describe data elements, or lists no field groups); a failed lookup is retried on the next metadata load. The memory moves into withArcGISContingentValues as an explicit knownAbsent set, with saves passing fresh. * Address Claude review feedback - Report a nonhosted layer's contingent values unavailable, holding the edits they could affect, when the service says it supports queryDataElements but that request fails; only a service that does not support it, or whose own metadata cannot be read, counts as having none. | 3 天前 | |
feat(plugins): USGS NLDI and Reverse Geocode on ArcGIS and the globe (#3103) * feat(plugins): USGS NLDI and Reverse Geocode on ArcGIS and the globe Both plugins open a MapLibre Popup, which needs a MapLibre map: it reads the map transform, so addTo throws on a mapbox-gl map and the ArcGIS and Cesium control maps have nothing for it to read. Add createMapPopup (map-popup.ts): MapLibre's own Popup on a MapLibre map, otherwise the same markup and classes placed through project() on every frame, as annotation-marker.ts does for markers. Route both plugins through it and getControlMap, and declare all four engines. - The Cesium control map fires `render` from the scene's postRender (only while someone listens), so a pinned element follows the camera instead of the coarse camera.changed threshold. - The Cesium control map drops the click that ends a drag, as MapLibre's 3 px click tolerance does. The browser fires click after any press and release, so panning the globe also triggered click-driven controls. - Document both plugins in the ArcGIS, Cesium and Mapbox renderer pages. * Address review feedback - Consume the Cesium facade's press state on every click and clear it on pointercancel, keeping the consumed press for the dblclick that follows. A later click with no press of its own (keyboard or dispatched) was measured against a drag's stale press and dropped. - Give createMapPopup a closeButtonLabel option, applied to both the projected popup and MapLibre's own close button, and pass Reverse Geocode's translated label (new en.json key geocode.reverseClosePopup) instead of the hardcoded English aria-label. | 18 天前 | |
# feat(processing): multi-threaded WebAssembly geoprocessing with SIMD128 and adaptive worker pool (#3203) * feat(processing): multi-threaded WebAssembly geoprocessing with SIMD128 and worker pool * style: auto-format (ruff + oxfmt) [pre-commit.ci] * Address CodeRabbit review feedback - Fix the shared-memory probe: its memory section declared 5 bytes but held 4, so WebAssembly.validate always returned false and threaded-simd could never activate. Add a test that runs the real probe. - Fall back to one thread when maxThreads/recommendedThreads is not finite, so a NaN cannot make the pool capacity NaN and stall the queue. - Keep releaseIdleWasmToolWorkers to idle workers only; track a fail() per busy worker so terminateAllWasmToolWorkers rejects in-flight runs (terminate() fires no event) and clears their ack timers. - Route post/error/messageerror/abort through one fail() helper that rejects the run and then dispatches the next queued job, so a failed postMessage no longer strands the queue. - Reject a queued job as soon as its signal aborts. - Expire parked workers beyond the first after 30 s and trim the idle pool to the current capacity. - Cancel a parallel batch's sibling runs once one run fails. - Remove the benchmark script and its docs section: it timed JS loops and sequential chunking, not the WASM SIMD kernel or the worker pool. - Remove the numerical tests that only checked their own inline formulas. - Document both service-worker reload paths (controllerchange offer and the stale-chunk reload) and restore the dropped precache sentence. - wasm-convert tests now reset the pool with terminateAllWasmToolWorkers, since a run left in flight holds the single slot. * Address review feedback - Restore per-run workers outside threaded-simd: capacity was 1 in the default non-isolated, desktop and embed builds, so concurrent Whitebox runs queued behind each other (a long tiling job blocked every short tool). Only threaded-simd bounds the pool now; other modes keep one warm worker, as before. - Docs: state that every mode runs the same binary with private memory and only changes worker count; say nginx does not ship the COOP/COEP headers; make the require-corp warning prominent. - Keep only the isolation headers in the vite preview block; the pinned port and host changed every `vite preview` run. - Simplify recommendedThreads to min(cores, 4) and assume one core without navigator. - dispatchNext loops while a slot is free, so a dequeued job that settles without taking the slot (aborted, spawn throws) no longer strands the jobs behind it. * Address Claude review feedback - Bound the worker pool only when the caller explicitly requests executionMode "threaded-simd". Auto mode picks threaded-simd on any cross-origin-isolated page, where a 1-4 worker cap queued short tools behind a long tiling job for no gain (the workers share no memory). - Stop exporting the test-only setMockWasmCapabilities and the redundant probeWasmCapabilities alias from the package API; the test imports the mock from its module. - Drop VITE_CROSS_ORIGIN_ISOLATION from BUILD_ENV_KEYS (it configures the servers only and is read before the allowlist runs) and share one header block between server and preview. - Docs: retitle the section, drop the unverifiable SIMD instruction count, sync the classification lists with ALGORITHM_PROFILES, and say the classification is advisory. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: giswqs <giswqs@gmail.com> | 3 天前 | |
feat(cesium): label anchor, wrapping and overrides; hide far-side markers (#3092) * feat(cesium): label anchor, wrapping and overrides; hide far-side markers Part of #3088. - Globe labels follow `anchor` (centred for line placement, as on the 2D map), wrap at `maxWidth` ems, and evaluate the data-defined size, colour, opacity and visibility overrides per feature. An opacity override replaces the layer opacity as on the 2D map, and the in-place opacity restyle now rescales each label's own colours instead of repainting every label in the layer's one colour. - Store points, labels, cluster bubbles and batched points drew through the Earth (`disableDepthTestDistance: Infinity`), so far-side cities showed over the near side. Their depth-test distance now follows the camera's horizon distance (cesium-horizon.ts): near-side markers still draw over terrain, far-side ones are hidden by the globe. - Regenerate the call-log fixture for the new label writes. Cesium labels have no rotation or collision pass, so `rotation`, `allowOverlap`, the priority override and text along a line's path remain 2D-only; the docs say so. * Address CodeRabbit review feedback - Fade a label's data-defined opacity with an active story fade, scaled by how far the fade has taken the layer from its own opacity, so a story fade to 0 hides those labels along with the rest of the layer. - Re-run clustering when the horizon distance moves more than 5% since the bubbles were built, so their depth-test distance does not go stale between camera.changed's coarse cluster passes; the subscription ends on dispose. * Address Claude review feedback - Extend the horizon depth distance by how far past the smooth horizon the highest terrain stays in view, so a marker on a distant ridge at a low camera height still skips the depth test instead of being clipped by the hill it sits on. | 18 天前 | |
feat(plugins): USGS NLDI and Reverse Geocode on ArcGIS and the globe (#3103) * feat(plugins): USGS NLDI and Reverse Geocode on ArcGIS and the globe Both plugins open a MapLibre Popup, which needs a MapLibre map: it reads the map transform, so addTo throws on a mapbox-gl map and the ArcGIS and Cesium control maps have nothing for it to read. Add createMapPopup (map-popup.ts): MapLibre's own Popup on a MapLibre map, otherwise the same markup and classes placed through project() on every frame, as annotation-marker.ts does for markers. Route both plugins through it and getControlMap, and declare all four engines. - The Cesium control map fires `render` from the scene's postRender (only while someone listens), so a pinned element follows the camera instead of the coarse camera.changed threshold. - The Cesium control map drops the click that ends a drag, as MapLibre's 3 px click tolerance does. The browser fires click after any press and release, so panning the globe also triggered click-driven controls. - Document both plugins in the ArcGIS, Cesium and Mapbox renderer pages. * Address review feedback - Consume the Cesium facade's press state on every click and clear it on pointercancel, keeping the consumed press for the dblclick that follows. A later click with no press of its own (keyboard or dispatched) was measured against a drag's stale press and dropped. - Give createMapPopup a closeButtonLabel option, applied to both the projected popup and MapLibre's own close button, and pass Reverse Geocode's translated label (new en.json key geocode.reverseClosePopup) instead of the hardcoded English aria-label. | 18 天前 | |
docs: add a How to Cite page with DOI and citation formats (#704) * docs: add a How to Cite page with DOI and citation formats Add a dedicated citation section to the online documentation as requested in #701. The new docs/citation.md page documents the recommended citation, BibTeX and APA formats, the Zenodo concept DOI badge, and points to the existing CITATION.cff for GitHub's Cite this repository button. Wire it into the mkdocs Reference nav and add a matching Citation section to the README. Fixes #701 * Address Claude review feedback - Add the publication year (2026, from CITATION.cff date-released) to the recommended citation, BibTeX (year field), and APA entries in docs/citation.md, so dated-release citations render correctly and conform to APA 7's (YYYY) placement. - Mirror the year fix in the README Citation blockquote and wrap the bare DOI URL in <...> for style consistency with the docs page. * docs: use the full descriptive title in citation entries Update the cited title to GeoLibre: A lightweight, cloud-native GIS platform for visualizing, exploring, and analyzing geospatial data across the recommended citation, BibTeX, APA, and README blockquote. | 4 个月前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
feat(data): add ICESat-2 and GEDI spaceborne LiDAR footprints (#3079) * feat(data): add ICESat-2 and GEDI spaceborne LiDAR footprints Add Data -> ICESat-2 / GEDI reads a local HDF5 granule of ICESat-2 ATL06/ATL08 or GEDI L2A/L2B/L4A in the browser (h5wasm) and adds its footprints as a GeoJSON point layer. The NetCDF reader skipped these products because their per-footprint arrays are 1-D. The reader picks a product description from the root short_name (or the DAAC file name), lists beams and every 1-D field aligned with the footprints, applies the product's quality flag and fill values, and adds beam, beam type, UTC time and along-track distance to each feature. It can limit the read to the current view and thins every beam evenly to a point cap. The new layer is colored by the product's main field, so the attribute table charts give an along-track profile. Refs #3078 * Address review feedback - Thin footprints with one stride over all beams' matches, so maxPoints caps the total; restarting the index per beam kept the first match of every beam and could exceed the cap (CodeRabbit). - Null 64-bit integer fields that equal their _FillValue, compared as BigInt so the fill is not lost to float64 rounding (Claude). - Fit a track that crosses the antimeridian with unwrapped bounds instead of zooming out to the whole world; pointBounds moves to lib/ so it can be unit-tested (Claude). * Address review feedback - Fall back to the default point cap when the Maximum footprints box is empty or invalid, instead of lifting the cap and building a million-feature layer from a full GEDI orbit (Claude). - Compare a numeric 64-bit _FillValue only when it is a safe integer, as a BigInt, so a rounded fill cannot null a neighboring shot number; test added (CodeRabbit). * Address Claude review feedback - Drop an Add whose granule was closed during the pre-read yield (dialog closed or another file picked), instead of reading the closed file and reporting "No footprints matched" for the wrong granule. * Address Claude review feedback - Say what the quality filter does for each product under the checkbox, and relabel it "Apply the product's quality filter": ATL08 has no quality flag and only drops segments without a terrain height, so "pass the product's quality flag" overstated it. - Drop the unreachable shift in pointBounds: the shifted range is only narrower when points straddle 180°, which keeps west360 in [0, 180]. * Address CodeRabbit review feedback - Clear the busy state when another file is picked: a submit superseded during its pre-read yield returns early without clearing it, which left the Add button disabled for the newly opened granule. * Address Claude review feedback - Clamp a fractional maxPoints to at least 1, so 0.5 no longer floors to 0 and yields an infinite stride. - Keep the first field with a name and rename only later duplicates to their path, so a product's default names (and the color-by primary field) stay stable when another dataset shares a name. * feat(data): ICESat-2/GEDI sample granules, resizable dialog, Files section - Add a Sample data dropdown with one granule per product (ATL06, ATL08, GEDI L2A/L2B/L4A) hosted on Source Cooperative, downloaded with a progress readout into a preallocated buffer and cancelled when the dialog closes or another file is picked. - Stop the horizontal scrollbar: the dialog body is a grid whose column grew to the longest unbreakable HDF5 path (ATL06), so the form gets min-w-0 and field paths truncate. - Widen the default dialog and add a corner resize grip, through a useDialogResize hook that follows the layer metadata dialog's grip. - Move the menu entry from 3D layers to Files: the footprints render as flat points read from a granule file. * Split the ICESat-2/GEDI dialog and handle encoded sample downloads - check:untested-modules failed: the dialog reached 615 lines with no test loading it. Move the sample list, downloadWithProgress, fieldKey and baseName into lib/spaceborne-lidar-samples.ts (with tests), and the beam/field/filter controls into SpaceborneLidarOptions.tsx; the dialog is now 435 lines. - Read a content-encoded response whole instead of preallocating from Content-Length, which is the compressed size there and would overflow the buffer (Claude review). | 18 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
feat(embed): let a layout=viewer embed opt into drawing (#3154) * feat(embed): let a layout=viewer embed opt into drawing `layout=viewer` deactivates the geometry editor, so a host page that embeds the read-only viewer cannot let the user draw, even though getDrawnFeatures and featuresChanged (#3021) can read a drawing back. Add a `draw` URL flag. With `?layout=viewer&draw` the geometry editor is let through (`isViewerBlockedPlugin`), so `?plugin=geo-editor` or a project that lists it can open its toolbar. Annotations and GeoAgent stay blocked. The flag only takes effect when the deployment grants `project:edit`, and without it nothing changes. `draw` is reserved so it never becomes a tool parameter in a `?tool=` link. The viewer also stops offering ways to edit or move data around the deployment's capability gates: Identify no longer shows Edit geometry or Edit attributes (this was already reachable in `layout=viewer` before this change), and the editor toolbar drops its Open/Save file buttons. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(embed): set viewer file-tools flag during render, document drawing readback needs The geometry editor reads its file-tools flag once at construction, and the plugin restore and ?plugin= deep link construct it from effects. Setting the flag from an effect in the guard hook could lose that race against a child's effect, so set it while rendering, which precedes every effect. Add a render test for it and record why an empty fileModes list is safe upstream. Docs: reading drawings back needs the embed allowlist and the export:data capability, not only project:edit; use a self-hosted placeholder URL in the drawing example. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * Address review feedback - Move the viewer gate on Identify's edit actions into useIdentifyEditActions and pass usePluginDeepLink the layout options instead of two booleans, so DesktopShell.tsx stays within the untested-module growth allowance (it had reached 1341 lines against a 1334 cap once merged with main), which failed Build and test. - Note in useViewerPluginGuard that layoutOptions.viewer comes from the launch URL and is fixed for the page's lifetime, so the render-time file-tools flag can never go stale and needs no reset on unmount. --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-authored-by: giswqs <giswqs@gmail.com> | 8 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
feat(postgis): render PostGIS vector tiles natively on Android/iOS (#3172) * feat(postgis): render PostGIS vector tiles natively on Android/iOS The mobile apps cannot run the Martin tile server, so Add Data > PostgreSQL was hidden there (GeoLibre#2091). Render the tiles in-process instead: the Tauri backend connects to PostgreSQL directly (tokio-postgres + deadpool, rustls/ring) and builds each tile with ST_AsMVT, and MapLibre reaches it through a geolibre-pgtiles:// protocol. No process is spawned and no port is bound. - Tile URLs persist only the password-masked connection label; the protocol resolves it from this session's connects or the saved connections, so a reopened project's layers work without credentials in the project file. - The tile envelope is clipped to the table's extent before it is transformed, so projected CRSs (e.g. UTM) still render at low zoom. - SRID-0 columns use the rows' own SRID when they carry one, else the default SRID field. - sslmode follows libpq: prefer/require encrypt without verifying, and verify-ca/verify-full check against the webpki roots. - Mobile Tauri gets a tiles-only PostgreSQL form; desktop keeps Martin and the editable mode unchanged, and mobile browsers still hide the source. Tested on an Android phone (Redmi Note 9 Pro) against PostGIS 3.6.1 with EPSG:4326, 32748 and 54004 tables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address review findings on native PostGIS tiles Backend (postgis_tiles.rs): - Connect outside the global pool lock: one OnceCell slot per connection, so a slow host no longer stalls tiles from other databases and parallel first tiles share one connect. - Key pools by connection only; the default SRID moves into the plan key, so layers with different default SRIDs stop closing each other's pool. - SET statement_timeout in a post-create hook instead of the `options` startup parameter, which PgBouncer and hosted poolers reject. - Build each tile plan once per key (no stampede on first draw); a plan built without its extent clip is retried after 60 s, not cached forever. - source_info reuses the plan, and a failed extent yields bounds: None instead of failing the add. - Evict the least recently used pool, not the oldest. - Parse sslmode/sslrootcert like libpq (URI and quoted key/value forms), support sslrootcert PEM files, and implement verify-ca as chain-only. Frontend: - Mask password/sslpassword query parameters in connection labels so they never reach persisted tile URLs. - Queue tile requests per connection and drop ones MapLibre aborts. - Close a database's pool when its last layer is removed or the Add Data form closes unused; a replaced session connection is disconnected. - Note the certificate behaviour in the mobile notice and docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address code review of native PostGIS tiles Backend: - Evict only after a new connection succeeds, so a mistyped string never costs a pool that live layers use; slots still connecting don't count. - Never close a pool explicitly: eviction and disconnect drop the map's reference, and connections close when the last in-flight request ends. That stops in-flight tiles failing and covers a disconnect mid-connect. - One PostgisTileSourceRequest replaces the five loose command arguments and the repeated SourceKey construction; use f64::clamp. Frontend: - The Add Data form releases every pool it opened and no layer uses when it moves to another database or closes, not just the last one. - Shared helpers: savedPostgresConnectionsWithLabel, the POSTGIS_TILES_SOURCE_KIND constant, and a PostgresConnectionFields component used by both the Martin and the mobile forms. - MAX_TILES_IN_FLIGHT moves next to the URL helpers, and a test keeps it equal to the Rust POOL_SIZE (documented in docs/maintenance.md). i18n: - The reworded web notice gets a new key (webUnavailableNotice); the stale addData.postgres.desktopOnlyNotice is removed from every catalog so non-English users fall back to the correct English text. - New keys for the read-only table picker (tileSourceTable) and the unresolved-connection tile error, now thrown through i18next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address second CodeRabbit review of native PostGIS tiles - Keep serving an unclipped tile plan while one background task retries its extent, and double the retry wait after each failure (up to 1 h), so a slow or failing extent scan no longer stalls the layer's tiles. - Parse geolibre-pgtiles:// tile URLs by hand: Chromium and Android WebView before 130 read non-special schemes as an opaque path with no host, so every tile failed to parse there. - Mask connection labels with the regex path when the URL parser finds no host, so those WebViews no longer leave the userinfo password in the persisted label. - Docs: sslmode=prefer can fall back to plaintext; require, verify-ca or verify-full make encryption mandatory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): single plan rebuild guard and bounded password mask - PlanRetry tracks an in-flight rebuild, released by a drop guard however the task ends, so a rebuild that outlasts its retry delay can no longer be joined by a second one. - The userinfo password regex stops at `/`, `?` and `#`, so a port followed by an `@` in the query (`host:5432/db?application_name=a@b`) is no longer masked as a password and the label keeps its port and database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 6 天前 | |
chore(release): v3.5.2 (#3268) | 20 小时前 | |
docs(gallery): add NASA OPERA demos 101-105 (#2943) Adds Alps radar, Valencia floods, Canada wildfire season 2023, Los Angeles fire scars and Amazon water extent to the open data gallery and bumps the demo count to 105. | 23 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
docs(i18n): clarify how English strings name other UI elements (#3244) * docs(i18n): clarify how English strings name other UI elements A reference to another part of the interface quotes that element's label exactly ("the Add data menu", "the Layers panel"), and words formed from people's names, such as "Gaussian", keep their capital. Follow-up to #3243, whose last push landed after it merged. * Address Claude review feedback - Say that a referenced label keeps its exact capitalization while the generic noun after it (panel, button, menu) stays lowercase. * style: auto-format (ruff + oxfmt) [pre-commit.ci] * Remove unrelated changes swept into this branch An earlier commit here picked up uncommitted work from another change in the same checkout (Measure and minimap UI-control options). Restore those files to main so this PR only touches docs/i18n.md. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> | 1 天前 | |
chore(release): v3.5.0 (#3209) | 3 天前 | |
feat(postgis): render PostGIS vector tiles natively on Android/iOS (#3172) * feat(postgis): render PostGIS vector tiles natively on Android/iOS The mobile apps cannot run the Martin tile server, so Add Data > PostgreSQL was hidden there (GeoLibre#2091). Render the tiles in-process instead: the Tauri backend connects to PostgreSQL directly (tokio-postgres + deadpool, rustls/ring) and builds each tile with ST_AsMVT, and MapLibre reaches it through a geolibre-pgtiles:// protocol. No process is spawned and no port is bound. - Tile URLs persist only the password-masked connection label; the protocol resolves it from this session's connects or the saved connections, so a reopened project's layers work without credentials in the project file. - The tile envelope is clipped to the table's extent before it is transformed, so projected CRSs (e.g. UTM) still render at low zoom. - SRID-0 columns use the rows' own SRID when they carry one, else the default SRID field. - sslmode follows libpq: prefer/require encrypt without verifying, and verify-ca/verify-full check against the webpki roots. - Mobile Tauri gets a tiles-only PostgreSQL form; desktop keeps Martin and the editable mode unchanged, and mobile browsers still hide the source. Tested on an Android phone (Redmi Note 9 Pro) against PostGIS 3.6.1 with EPSG:4326, 32748 and 54004 tables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address review findings on native PostGIS tiles Backend (postgis_tiles.rs): - Connect outside the global pool lock: one OnceCell slot per connection, so a slow host no longer stalls tiles from other databases and parallel first tiles share one connect. - Key pools by connection only; the default SRID moves into the plan key, so layers with different default SRIDs stop closing each other's pool. - SET statement_timeout in a post-create hook instead of the `options` startup parameter, which PgBouncer and hosted poolers reject. - Build each tile plan once per key (no stampede on first draw); a plan built without its extent clip is retried after 60 s, not cached forever. - source_info reuses the plan, and a failed extent yields bounds: None instead of failing the add. - Evict the least recently used pool, not the oldest. - Parse sslmode/sslrootcert like libpq (URI and quoted key/value forms), support sslrootcert PEM files, and implement verify-ca as chain-only. Frontend: - Mask password/sslpassword query parameters in connection labels so they never reach persisted tile URLs. - Queue tile requests per connection and drop ones MapLibre aborts. - Close a database's pool when its last layer is removed or the Add Data form closes unused; a replaced session connection is disconnected. - Note the certificate behaviour in the mobile notice and docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address code review of native PostGIS tiles Backend: - Evict only after a new connection succeeds, so a mistyped string never costs a pool that live layers use; slots still connecting don't count. - Never close a pool explicitly: eviction and disconnect drop the map's reference, and connections close when the last in-flight request ends. That stops in-flight tiles failing and covers a disconnect mid-connect. - One PostgisTileSourceRequest replaces the five loose command arguments and the repeated SourceKey construction; use f64::clamp. Frontend: - The Add Data form releases every pool it opened and no layer uses when it moves to another database or closes, not just the last one. - Shared helpers: savedPostgresConnectionsWithLabel, the POSTGIS_TILES_SOURCE_KIND constant, and a PostgresConnectionFields component used by both the Martin and the mobile forms. - MAX_TILES_IN_FLIGHT moves next to the URL helpers, and a test keeps it equal to the Rust POOL_SIZE (documented in docs/maintenance.md). i18n: - The reworded web notice gets a new key (webUnavailableNotice); the stale addData.postgres.desktopOnlyNotice is removed from every catalog so non-English users fall back to the correct English text. - New keys for the read-only table picker (tileSourceTable) and the unresolved-connection tile error, now thrown through i18next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): address second CodeRabbit review of native PostGIS tiles - Keep serving an unclipped tile plan while one background task retries its extent, and double the retry wait after each failure (up to 1 h), so a slow or failing extent scan no longer stalls the layer's tiles. - Parse geolibre-pgtiles:// tile URLs by hand: Chromium and Android WebView before 130 read non-special schemes as an opaque path with no host, so every tile failed to parse there. - Mask connection labels with the regex path when the URL parser finds no host, so those WebViews no longer leave the userinfo password in the persisted label. - Docs: sslmode=prefer can fall back to plaintext; require, verify-ca or verify-full make encryption mandatory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(postgis): single plan rebuild guard and bounded password mask - PlanRetry tracks an in-flight rebuild, released by a drop guard however the task ends, so a rebuild that outlasts its retry delay can no longer be joined by a second one. - The userinfo password regex stops at `/`, `?` and `#`, so a port followed by an `@` in the query (`host:5432/db?application_name=a@b`) is no longer masked as a password and the label keeps its port and database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 6 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
fix(nasa-earthdata): fall back from a GIBS default date with no tiles (#3261) * fix(nasa-earthdata): fall back from a GIBS default date with no tiles GIBS sometimes advertises a default (latest) date in its WMTS capabilities that has no imagery: MOPITT monthly CO defaults to 2024-11-01, where every tile is a 404, so adding it drew nothing and raised a "No tiles found" toast. A panel Add of a time-enabled layer now probes the zoom-0 tile at the default date first. On a 404 it steps back through the advertised time domain (at most three earlier dates) and adds the layer at the newest date that has imagery. A default date that works costs one tile request and is kept; adds that name a date or key (project restore, date picker) are untouched. Fixes #3259 * fix(nasa-earthdata): harden the default-date probe wrapper Address review feedback on the GIBS default-date fallback: - Move the addLayer wrapper into nasa-earthdata-date-fallback.ts and test it with a fake control (date/key pass-through, deactivation, fallback and default paths). - Time out every probe with an AbortController instead of relying on AbortSignal.timeout. - Add the layer at its default date if the probe chain rejects, so the Add button can never go silently dead. - Treat a zero period (P0D) as unsteppable instead of returning the same date again. * Address Claude review feedback - Clamp the day when stepping back by a month or year period, so 2024-03-31 minus P1M is 2024-02-29 rather than the Date.UTC rollover 2024-03-02, a date GIBS never advertises. Test added. * Address review feedback - Step back from a fixed anchor date rather than from the last clamped date, so 2024-03-31 by P1M gives 2024-02-29 then 2024-01-31 (not 2024-01-29, which is off the advertised grid). Test extended. - Log a failing deferred addLayer instead of leaving an unhandled rejection, since the add now runs after the click handler returned. * Address CodeRabbit review feedback - Re-anchor date stepping whenever the containing interval changes, so moving from a monthly into an overlapping daily interval steps from the current date with the new period instead of from the old monthly anchor (which could return a date later than the previous one). Test added. * fix(nasa-earthdata): step the date fallback on the period grid The default-date fallback stepped back from the current date, so a default that is not a step of its interval's period (e.g. 2024-03-20 on a 12-day grid from 2024-02-25) moved every later date off the grid. Step from the interval's start instead, so each probed date is one GIBS advertises. Pin the panel Add wiring and addLayer's date/key options in the upstream contract tests, and note the dependency in maintenance.md. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Applied by the claude-autofix workflow. * Address review feedback - Ignore a repeat panel Add for a layer whose date probe is still running. Upstream gives a repeat add at the same date its own "#2" instance, so a double click during the probe added a duplicate layer. An Add after the probe settles still goes through. Test added. --------- Co-authored-by: giswqs <5016453+giswqs@users.noreply.github.com> | 1 天前 | |
feat(map): request headers for authenticated tile services (#3142) * feat(map): request headers for authenticated tile services MapLibre takes one request transform per map, so a plugin that needs a header on its tile requests has to call setTransformRequest itself and replaces anyone else's (GeoLens did, for private rasters). GeoLibre now builds its MapLibre maps with a single transform backed by a header registry in @geolibre/map/tile-request-headers, keyed by owner and matched by URL prefix, and GeoLens registers its API keys there. Plugins get a headers option on addVectorTileLayer and setLayerRequestHeaders for any tile layer, so a token refresh needs no reload. Headers stay in memory: they never reach the store or a saved project, and opening another project or removeLayer drops them. Only MapLibre maps send them. Closes #3127 * fix(map): keep tile request headers to their own server and layer - A URL prefix must now name one host and the start of a path on it before it can carry headers. A template with a placeholder in its host matched on "https://", and a prefix without its trailing slash matched look-alike hosts, so a layer's credentials could reach basemaps and other servers. The registry throws for such a prefix, and setLayerRequestHeaders and addVectorTileLayer say why. - A layer's headers are dropped when the layer leaves the store, however it is removed (the Layers panel, undo, a plugin), not only through the plugin API's removeLayer. - Header names given twice in different cases are rejected, since fetch would join their values into one. * fix(map): drop tile headers when a layer's URL moves, and match fetch's rules - A layer's headers are recorded with the tile URL prefixes they were set for, and dropped when the layer's URL moves to other prefixes, so a new server doesn't inherit them and the old prefix doesn't keep them. A token refresh that only changes the query string after the placeholders keeps the same prefixes and the headers. - Header validation now also rejects what fetch won't send: names the browser sets itself (Cookie, Host, Sec-*, Proxy-* and the rest of the Fetch standard's forbidden names), which fetch silently drops, and values with characters above U+00FF, which make fetch throw inside MapLibre. - GeoLens checks the renderer before registering a private raster's API key, so the key isn't left registered when the call refuses. | 13 天前 | |
feat(plugins): tell plugins which CRS the map is drawn in (#3214) Add getMapCrs and onMapCrsChange to the plugin app API. getMapCrs returns { id, code, wmsSrs? } for a MapLibre map drawn in another CRS (preferences.map.mapCrs), or null on the default Web Mercator map, the globe and the other renderers. onMapCrsChange reports changes. The map controller fires a geolibre:map-crs-change window event when it enters or leaves a CRS, and when it is torn down in one, so a renderer swap is reported too. The host reads the primary engine's new getMapCrs and drops events that do not change the value. Document the API, and note in the addWmsLayer docs that a WMS listed only in the map's own CRS lines up on both builds. Fixes #3213 | 2 天前 | |
feat(mcp): add read-only map previews with MCP Apps (#3097) | 18 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
feat/support XYZ Layer with {-y} placeholder (#3265) * support XYZ Layer with {-y} placeholder GeoLibre XYZ layers now accept {-y} in a tile URL and in a TileJSON entry, and flip that row the way QGIS and https://viewer.gishub.vn do. * fix bot comments * fix oxfmt * fix minor bot comments * fix storymap export to deal with {-y} raster tile | 22 小时前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
feat: let projects open Measure and Minimap collapsed, with Measure units (#3245) * feat: let projects open Measure and Minimap collapsed, with Measure units A project's interaction.controls entry for measure or minimap can now be an object, {"visible": true, "collapsed": true, "distanceUnit": "feet", "areaUnit": "acres"}, instead of a plain boolean. collapsed opens only the control's on-map button, so a shared or HTML-exported map no longer starts with the Measure panel over it and its tool turning the viewer's first clicks into points. A plain true keeps today's expanded behaviour. - Python: show_control(name, visible, *, collapsed, distance_unit, area_unit), validated and round-tripped through save/load/to_html. - openControlPanel accepts Measure options; Minimap gains collapsed. - Measure builds its panel on first expand, so the terrain section and resize styling now attach on that expand when it opens collapsed. - New units on an open Measure control rebuild it, since its unit dropdown only reads them when the panel is built. Fixes #3241 * Address review feedback - Widget replay forwards control options only for measure and minimap, matching the desktop restore hook, so a stray option cannot keep another panel closed. - openMeasurePanel returns early when nothing changes on an open control, and a rebuild for new units keeps a folded ruler folded. - Minimap applies an explicit collapsed request immediately, so a basemap refresh in the same turn rebuilds it in the requested state. - show_control rejects a non-boolean collapsed instead of coercing it. * Address Claude review feedback - Add a test that the Python Measure unit sets match the TypeScript lists in measure.ts, like the existing control-list drift test. * Address Claude review feedback - The widget replays every control on each _ui change; re-sending a collapsed option would fold a Measure or Minimap panel the viewer had since opened. Send a setting with options only when it changed, and forget what was sent when the iframe reports ready again. | 1 天前 | |
feat: let projects open Measure and Minimap collapsed, with Measure units (#3245) * feat: let projects open Measure and Minimap collapsed, with Measure units A project's interaction.controls entry for measure or minimap can now be an object, {"visible": true, "collapsed": true, "distanceUnit": "feet", "areaUnit": "acres"}, instead of a plain boolean. collapsed opens only the control's on-map button, so a shared or HTML-exported map no longer starts with the Measure panel over it and its tool turning the viewer's first clicks into points. A plain true keeps today's expanded behaviour. - Python: show_control(name, visible, *, collapsed, distance_unit, area_unit), validated and round-tripped through save/load/to_html. - openControlPanel accepts Measure options; Minimap gains collapsed. - Measure builds its panel on first expand, so the terrain section and resize styling now attach on that expand when it opens collapsed. - New units on an open Measure control rebuild it, since its unit dropdown only reads them when the panel is built. Fixes #3241 * Address review feedback - Widget replay forwards control options only for measure and minimap, matching the desktop restore hook, so a stray option cannot keep another panel closed. - openMeasurePanel returns early when nothing changes on an open control, and a rebuild for new units keeps a folded ruler folded. - Minimap applies an explicit collapsed request immediately, so a basemap refresh in the same turn rebuilds it in the requested state. - show_control rejects a non-boolean collapsed instead of coercing it. * Address Claude review feedback - Add a test that the Python Measure unit sets match the TypeScript lists in measure.ts, like the existing control-list drift test. * Address Claude review feedback - The widget replays every control on each _ui change; re-sending a collapsed option would fold a Measure or Minimap panel the viewer had since opened. Send a setting with options only when it changed, and forget what was sent when the iframe reports ready again. | 1 天前 | |
docs: install the R package from CRAN (#2237) The geolibre R package 0.2.0 is on CRAN, so the R guide and the getting started page no longer describe GitHub as the only install path. Claude-Session: https://claude.ai/code/session_01BRUGY3CqphbC1FNhkZJKBt | 1 个月前 | |
chore(release): v3.5.2 (#3268) | 20 小时前 | |
feat(map): request headers for authenticated tile services (#3142) * feat(map): request headers for authenticated tile services MapLibre takes one request transform per map, so a plugin that needs a header on its tile requests has to call setTransformRequest itself and replaces anyone else's (GeoLens did, for private rasters). GeoLibre now builds its MapLibre maps with a single transform backed by a header registry in @geolibre/map/tile-request-headers, keyed by owner and matched by URL prefix, and GeoLens registers its API keys there. Plugins get a headers option on addVectorTileLayer and setLayerRequestHeaders for any tile layer, so a token refresh needs no reload. Headers stay in memory: they never reach the store or a saved project, and opening another project or removeLayer drops them. Only MapLibre maps send them. Closes #3127 * fix(map): keep tile request headers to their own server and layer - A URL prefix must now name one host and the start of a path on it before it can carry headers. A template with a placeholder in its host matched on "https://", and a prefix without its trailing slash matched look-alike hosts, so a layer's credentials could reach basemaps and other servers. The registry throws for such a prefix, and setLayerRequestHeaders and addVectorTileLayer say why. - A layer's headers are dropped when the layer leaves the store, however it is removed (the Layers panel, undo, a plugin), not only through the plugin API's removeLayer. - Header names given twice in different cases are rejected, since fetch would join their values into one. * fix(map): drop tile headers when a layer's URL moves, and match fetch's rules - A layer's headers are recorded with the tile URL prefixes they were set for, and dropped when the layer's URL moves to other prefixes, so a new server doesn't inherit them and the old prefix doesn't keep them. A token refresh that only changes the query string after the placeholders keeps the same prefixes and the headers. - Header validation now also rejects what fetch won't send: names the browser sets itself (Cookie, Host, Sec-*, Proxy-* and the rest of the Fetch standard's forbidden names), which fetch silently drops, and values with characters above U+00FF, which make fetch throw inside MapLibre. - GeoLens checks the renderer before registering a private raster's API key, so the key isn't left registered when the call refuses. | 13 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
docs: review the docs against the code and fix drift (#3008) * docs: review the docs against the code and fix drift Check every docs page against the current code and correct what no longer matches: menu paths and labels, plugin placement (most plugins now open in a docked panel), Cesium ion tokens being optional, desktop OAuth sign-in for sharing, browser project save/open, project schema fields, server and collaboration endpoints, Python and MCP APIs, and stale paths in the source-code deep dives. Fix the Spatial SQL tutorial's ST_Area_Spheroid query, which needs ST_FlipCoordinates for lat/lon axis order. Document the Settings sections that were listed but never described (Language, Appearance, Interface, Geocoding, AI Providers), and add the USGS NLDI and ArcGIS feature editing pages to the nav. * docs: keep the NLDI and ArcGIS editing pages out of the nav * Address CodeRabbit review feedback - collaboration.md: give both snapshot-cap defaults, 10 MB for the relay and 1 MB in the Docker Compose setup. - features.md, cesium-renderer.md: without an Ion token the globe still gets terrain from keyless Terrarium elevation (or a configured COG), not a bare ellipsoid (cesium-engine.ts enableWorldTerrain). * Address CodeRabbit review feedback - project-format.md: type blankBackgroundColor and selectedLayerId as string | null, matching ProjectFile in packages/core/src/types.ts. | 21 天前 | |
docs: add Terms of Service page for Earth Engine OAuth verification (#1177) * docs: add Terms of Service page for Earth Engine OAuth verification Google's OAuth app verification for Earth Engine requires a hosted Application Terms of Service link. Add docs/terms.md (published at https://geolibre.app/terms/), including a Google Earth Engine section covering own-account auth, Limited Use of Google user data, and links to Google's own terms. Register it in the mkdocs nav and cross-link it from the Privacy Policy. * Address review feedback - Fix redundant "(GeoLibre, the app)" definition in the opening line; now defines only "the app" (Claude review). - Name the license explicitly as the MIT License and link to the repo's LICENSE file instead of the generic repo URL (Claude review). - Qualify the "processed locally" claim in Your content to note that enabling online features (e.g. collaboration) may transmit data, per the Privacy Policy (CodeRabbit). | 3 个月前 | |
feat: startup layers and shareable interface files (#3039) * feat: startup layers and shareable interface files Startup settings could only preload layer styles. A layers file (Project > Export > Export Layers) now seeds every new project with URL- or path-referenced layers, and Settings > Interface can export and import the language, layout, theme and profile from a file or URL. * Address Claude review feedback - Fetch features only for the layers the Startup setting seeded, not every URL GeoJSON layer in whatever project startup opened. - Clear undo history after the startup fetch lands in a clean workspace, so undo cannot strip the fetched features back out. - Cap interface files at 256 KB (and a declared oversize Content-Length) before parsing. - Make normalizeLayersFileContent catch parser errors and apply the 1 MB cap, so a corrupt or oversized settings copy cannot break settings loading. * Address review feedback - Seed the Startup setting's layers when the restore gate times out too, and move the restore's ownership check onto the seeded workspace so a slow restore can still land (CodeRabbit). - Merge a partial interface file field by field onto the current settings, so a file setting only hiddenPlugins keeps the rest of the profile (CodeRabbit). - Let newProject take seed layers and use it for File > New and startup seeding, so its resets (attribute filter, selection) still apply (Claude). - Apply the startup fetch with withoutHistory (zundo pause) instead of clearing all undo history afterwards (Claude). - Read a URL interface file as a capped stream regardless of Content-Length, and re-check the stored profile lock before applying an import (Claude). - Build the Export submenu from a list, keeping ProjectMenu.tsx under the untested-module ratchet's 500-line threshold (CI). | 20 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 4 个月前 | ||
| 2 个月前 | ||
| 8 天前 | ||
| 1 天前 | ||
| 4 个月前 | ||
| 7 天前 | ||
| 25 天前 | ||
| 6 天前 | ||
| 3 天前 | ||
| 18 天前 | ||
| 3 天前 | ||
| 18 天前 | ||
| 18 天前 | ||
| 4 个月前 | ||
| 21 天前 | ||
| 21 天前 | ||
| 21 天前 | ||
| 18 天前 | ||
| 21 天前 | ||
| 8 天前 | ||
| 21 天前 | ||
| 6 天前 | ||
| 20 小时前 | ||
| 23 天前 | ||
| 21 天前 | ||
| 1 天前 | ||
| 3 天前 | ||
| 6 天前 | ||
| 21 天前 | ||
| 1 天前 | ||
| 13 天前 | ||
| 2 天前 | ||
| 18 天前 | ||
| 21 天前 | ||
| 22 小时前 | ||
| 21 天前 | ||
| 1 天前 | ||
| 1 天前 | ||
| 1 个月前 | ||
| 20 小时前 | ||
| 13 天前 | ||
| 21 天前 | ||
| 21 天前 | ||
| 3 个月前 | ||
| 20 天前 |