The LIPAS Legacy WFS (Web Feature Service) provides backward compatibility with the original WFS service implemented in 2012. This system maintains the exact layer structure, naming conventions, and data formats required by existing client applications and integrations.
The primary motivation for this implementation is to facilitate the retirement of the legacy server and database infrastructure while maintaining service continuity for dependent systems. This compatibility layer ensures that existing WFS clients can continue to operate without modification.
Important: This compatibility layer is maintained for legacy support purposes only. New implementations should follow contemporary API and naming standards.
The WFS system consists of several key components:
- Data Transformation Layer (
lipas.wfs.core): Converts LIPAS sports site data to legacy WFS format - Field Mappings (
lipas.wfs.mappings): Handles property name translation and data type conversion - Materialized Views: PostgreSQL views that provide optimized data access for Geoserver
- Geoserver Integration: REST API integration for layer management and publishing
LIPAS Sports Sites (PostgreSQL)
↓
Data Transformation (lipas.wfs.core/->wfs-rows)
↓
Legacy Field Mapping (lipas.wfs.mappings)
↓
WFS Master Table (wfs.master)
↓
Materialized Views (per type-code)
↓
Geoserver WFS Layers
The refresh-all! function performs a complete data refresh in two stages:
The refresh-wfs-master-table! function:
- Truncates the
wfs.mastertable - Iterates through all sports site type codes
- Fetches all active sites from the database for each type
- Transforms each site using
->wfs-rows(explodes multi-geometries into separate rows) - Applies legacy field mappings via
legacy-field->resolve-fn - Transforms geometries from EPSG:4326 to EPSG:3067 coordinate system
- Inserts processed data into
wfs.mastertable
The refresh-legacy-mat-views! function:
- Queries filtered data from
wfs.masterfor specific type codes - Applies geometry casting (2D vs 3D variants for LineString types)
- Orders fields using legacy field ordering for backwards compatibility
- Refreshes all materialized views
The system uses a two-tier mapping approach:
- Legacy Handle Mapping: Maps old property handles to current property names
- Field Resolution: Creates resolver functions for each legacy field
;; Example mapping flow:
:lighting-info → :valaistuksen_lisätieto → (comp :lighting-info :properties :site)All WFS layers include these common fields:
id: LIPAS site identifiernimi_fi,nimi_se,nimi_en: Site names in Finnish, Swedish, Englishtyyppikoodi: Type codetyyppi_nimi_fi/se/en: Type names in multiple languageskatuosoite,postinumero,postitoimipaikka: Address informationkuntanumero,kunta_nimi_fi: Municipality informationomistaja,yllapitaja: Owner and administratorthe_geom: Geometry in EPSG:3067
reitti_id: Auto-generated identifier for LineString features (1-based index)alue_id: Auto-generated identifier for Polygon features (1-based index)kulkusuunta: Travel direction for LineString features
Each type code has specific field mappings defined in type-code->legacy-fields:
;; Example for Pulkkamäki (1190)
1190 #{:koulun_liikuntapaikka
:valaistuksen_lisätieto
:yleiso_wc
:saa_julkaista_harrastuspassissa
:valaistus}View names follow strict patterns based on geometry type:
- Point types: Single view
["lipas_{type-code}_{name}"] - LineString types: Dual views
["lipas_{type-code}_{name}", "lipas_{type-code}_{name}_3d"] - Polygon types: Single view
["lipas_{type-code}_{name}"]
The following 9 type codes were added in 2024:
| Type Code | Name | Finnish Name | Geometry | View Name |
|---|---|---|---|---|
| 1190 | Sledding hill | Pulkkamäki | Point | lipas_1190_pulkkamaki |
| 1650 | Golf course | Golfkenttä | Polygon | lipas_1650_golfkentta |
| 2225 | Indoor playground/activity park | Sisäleikki-/sisäaktiviteettipuisto | Point | lipas_2225_sisaleikki_sisaaktiviteettipuisto |
| 2620 | Billiard hall | Biljardisali | Point | lipas_2620_biljardisali |
| 3250 | Water sports center | Vesiurheilukeskus | Point | lipas_3250_vesiurheilukeskus |
| 4406 | Multi-use trail | Monikäyttöreitti | LineString | lipas_4406_monikayttoreitti, lipas_4406_monikayttoreitti_3d |
| 4407 | Roller ski track | Rullahiihtorata | LineString | lipas_4407_rullahiihtorata, lipas_4407_rullahiihtorata_3d |
| 4441 | Dog sledding route | Koiravaljakkoreitti | LineString | lipas_4441_koiravaljakkoreitti, lipas_4441_koiravaljakkoreitti_3d |
| 6150 | Oval track | Ovaalirata | Point | lipas_6150_ovaalirata |
Views are created dynamically using:
- Type-specific fields from
type-code->legacy-fields - Common fields (id, name, contact info, location, etc.)
- Geometry handling with proper EPSG:3067 projection
- Data type casting (text, integer, boolean, timestamp)
The system supports three geometry types with proper EPSG:3067 projection:
- Point:
geometry(Point,3067)/geometry(PointZ,3067) - LineString:
geometry(LineString,3067)/geometry(LineStringZ,3067) - Polygon:
geometry(Polygon,3067)/geometry(PolygonZ,3067)
Layer publishing involves:
- Publishing featuretype from PostGIS materialized view
- Setting appropriate style based on geometry type
- Configuring spatial bounds for Finland (EPSG:3067)
- Managing layer groups for category-based organization
The system uses Geoserver's REST API for:
- Layer creation and deletion
- Style management
- Layer group organization
- Workspace configuration
Layers are organized into hierarchical groups:
- Main category groups: Based on type main categories (1000, 2000, etc.)
- Sub-category groups: Based on type sub-categories
- All sites group: Contains all published layers
Execute the following sequence via REPL:
;; 1. Refresh master table
(refresh-wfs-master-table! db)
;; 2. Create new materialized views
(create-legacy-mat-views! db)
;; 3. Publish new Geoserver layers
;; For each new view, use publish-layer function
(publish-layer "lipas_1190_pulkkamaki" "lipas_1190_pulkkamaki" "Point")
;; ... repeat for all new views
;; 4. Update layer groups (if needed)
(rebuild-all-legacy-layer-groups)After deployment, verify:
- All new materialized views exist in PostgreSQL
- All new layers are published in Geoserver
- Layer groups are properly organized
- WFS GetCapabilities shows new layers
- Sample WFS requests return expected data
The system maintains exact legacy field names, including:
- Finnish characters (ä, ö) in field names
- Underscores instead of hyphens
- Specific abbreviations (e.g.,
lkmfor count,m2for square meters)
- Enums: Converted to Finnish labels
- Boolean: Mapped to legacy boolean representation
- Numbers: Proper integer/float typing
- Dates: Helsinki timezone timestamps
All geometries are transformed to EPSG:3067 (Finnish national coordinate system) as required by legacy clients.
- Views are materialized for performance
- Refresh required after data changes
- Indexed on common query fields
- Efficient multi-geometry to single-geometry conversion
- Proper spatial indexing
- EPSG transformation optimized
To add support for new type codes:
- Define legacy field mappings in
type-code->legacy-fields - Define view names in
type-code->view-names - Verify property mappings in
legacy-field->resolve-fn - Test WFS row generation with sample data
- Execute deployment process
Common issues:
- Missing resolvers: Check
legacy-field->resolve-fnfor missing property mappings - Geometry errors: Verify EPSG:3067 transformation
- Field type mismatches: Check data type casting in view creation
- Geoserver errors: Verify REST API connectivity and authentication
- WFS layers are read-only
- Access controlled through Geoserver security
- No sensitive data exposed in legacy format
- Audit trail maintained in master table
src/clj/lipas/wfs/core.clj: Core WFS functionalitysrc/clj/lipas/wfs/mappings.clj: Field mappings and view definitionstest/clj/lipas/wfs/core_test.clj: Test suite with examplessrc/clj/lipas/integration/old_lipas/sports_site.clj: Legacy property mappings
refresh-all! [db]: Complete data refresh->wfs-rows [sports-site]: Convert site to WFS formatpublish-layer [feature-name publish-name geom-type]: Publish to Geoservercreate-legacy-mat-views! [db]: Create materialized viewsrebuild-all-legacy-layer-groups []: Rebuild layer groups
- Geoserver connection:
geoserver-config - Field ordering:
field-order - Layer groups:
main-category-layer-groups,sub-category-layer-groups
This documentation provides a comprehensive overview of the LIPAS Legacy WFS system, its architecture, data processing, and maintenance procedures. The system successfully maintains backward compatibility while leveraging modern infrastructure and practices.