From 10e96478ad345fff7638cb9ee16978731b0abc2c Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 10 Sep 2026 12:55:09 -0300 Subject: [PATCH 1/2] PYR1-1686 Publish GeoPackage layers under the path-joined store name The :geopackage branch aliased the feature type to the bare filename while :shapefile used store-name, so nested files lost their directory prefix: elmfire/landfire/fire-area_TS.gpkg published as fire-area_TS rather than elmfire_landfire_fire-area_TS. Pyregence parses the model and fuel back out of that name, so Risk with Ignition Pattern "Transmission lines" matched no layers for impacted structures, fire area and fire volume. --- src/geosync/core.clj | 9 ++++-- test/geosync/core_test.clj | 56 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/geosync/core.clj b/src/geosync/core.clj index 9ff2a21..6054983 100644 --- a/src/geosync/core.clj +++ b/src/geosync/core.clj @@ -247,20 +247,23 @@ (when matching-style [(rest/update-layer-style geoserver-workspace store-name matching-style :vector)]))) + ;; Publishes under store-name, not the bare filename: consumers parse the + ;; directory prefix back out of the layer name to recover the model and fuel + ;; (elmfire_landfire_fire-area_...), and a basename drops them. :geopackage (let [native-name (or native-name layer-name)] (doall (concat [(rest/create-data-store geoserver-workspace store-name file-url :geopackage) (rest/create-feature-type-via-put geoserver-workspace store-name file-url :geopackage)] - (when (not= native-name layer-name) + (when (not= native-name store-name) [(rest/create-feature-type-alias geoserver-workspace store-name native-name - layer-name) + store-name) (rest/delete-layer geoserver-workspace native-name) (rest/delete-feature-type geoserver-workspace store-name native-name)]) (when matching-style - [(rest/update-layer-style geoserver-workspace layer-name matching-style :vector)])))) + [(rest/update-layer-style geoserver-workspace store-name matching-style :vector)])))) :imagemosaic (do (update-properties-file! (str file-url "/datastore.properties") "schema" geoserver-workspace) (update-properties-file! (str file-url "/indexer.properties") "Name" store-name) diff --git a/test/geosync/core_test.clj b/test/geosync/core_test.clj index f626b78..71ede5e 100644 --- a/test/geosync/core_test.clj +++ b/test/geosync/core_test.clj @@ -1,6 +1,7 @@ (ns geosync.core-test - (:require [clojure.test :refer [deftest is testing]] - [geosync.core :as core])) + (:require [clojure.string :as s] + [clojure.test :refer [deftest is testing]] + [geosync.core :as core])) (defn geosync-conf ([] @@ -61,3 +62,54 @@ (testing "returns one spec if styles already exists and overwrite-styles is false" (is (= (count (core/file-paths->style-specs (geosync-conf {:overwrite-styles true}) #{"my-workspace:test-style"} ["test/data/test-style.css"])) 1)))) + +(defn- gpkg-file-spec + [store-name layer-name native-name] + {:store-type :geopackage + :store-name store-name + :layer-name layer-name + :native-name native-name + :file-url (str "file:///srv/gis/" store-name ".gpkg") + :style nil + :indexed? false}) + +(defn- published-feature-type-names + "The feature type names a spec list POSTs to the featuretypes endpoint." + [specs] + (->> specs + (filter (fn [[method uri]] + (and (= "POST" method) (s/ends-with? uri "/featuretypes")))) + ;; the first belongs to the nested ; the feature type's own follows it + (map (fn [[_ _ body]] (second (re-find #"([^<]+)" body)))))) + +(defn- deleted-feature-type-names + [specs] + (->> specs + (filter (fn [[method uri]] + (and (= "DELETE" method) (s/includes? uri "/featuretypes/")))) + (map (fn [[_ uri]] (last (s/split uri #"/")))))) + +(deftest geopackage-layer-specs-test + (testing "a nested GeoPackage publishes under the path-joined store name, not the bare filename" + (let [store-name "elmfire_landfire_fire-area_20260909_130000" + specs (core/file-spec->layer-specs (geosync-conf) + #{} + [] + (gpkg-file-spec store-name + "fire-area_20260909_130000" + "fire_area"))] + (is (= [store-name] (published-feature-type-names specs))) + (is (= ["fire_area"] (deleted-feature-type-names specs))))) + (testing "a flat GeoPackage keeps the name it publishes under today" + (let [specs (core/file-spec->layer-specs (geosync-conf) + #{} + [] + (gpkg-file-spec "state-boundaries" "state-boundaries" "states"))] + (is (= ["state-boundaries"] (published-feature-type-names specs))))) + (testing "no alias is created when the internal table already matches the store name" + (let [specs (core/file-spec->layer-specs (geosync-conf) + #{} + [] + (gpkg-file-spec "viirs-timestamped" "viirs-timestamped" "viirs-timestamped"))] + (is (empty? (published-feature-type-names specs))) + (is (= 2 (count specs)))))) From cac74a15b0c0cf8fe95b864cc3e91e95bcf2c97b Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 10 Sep 2026 14:43:44 -0300 Subject: [PATCH 2/2] remove useless comment --- src/geosync/core.clj | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/geosync/core.clj b/src/geosync/core.clj index 6054983..6d98294 100644 --- a/src/geosync/core.clj +++ b/src/geosync/core.clj @@ -247,9 +247,6 @@ (when matching-style [(rest/update-layer-style geoserver-workspace store-name matching-style :vector)]))) - ;; Publishes under store-name, not the bare filename: consumers parse the - ;; directory prefix back out of the layer name to recover the model and fuel - ;; (elmfire_landfire_fire-area_...), and a basename drops them. :geopackage (let [native-name (or native-name layer-name)] (doall (concat