From c650b1c50339c2784ad2747aadbe9dd2e6f8c5bf Mon Sep 17 00:00:00 2001
From: Riegel <alexander.riegel@hft-stuttgart.de>
Date: Fri, 13 Dec 2024 12:07:13 +0100
Subject: [PATCH] Refactor: Strip unsupported CRS parameters before parsing

---
 .../citydoctor2/parser/CityGmlParser.java     | 29 +++++++++++++++----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
index 495b2c0..a209fa4 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
@@ -55,6 +55,7 @@ import org.locationtech.proj4j.BasicCoordinateTransform;
 import org.locationtech.proj4j.CRSFactory;
 import org.locationtech.proj4j.CoordinateReferenceSystem;
 import org.locationtech.proj4j.ProjCoordinate;
+import org.locationtech.proj4j.io.Proj4FileReader;
 import org.locationtech.proj4j.proj.Projection;
 import org.locationtech.proj4j.units.Units;
 import org.xml.sax.InputSource;
@@ -87,6 +88,7 @@ import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -120,6 +122,10 @@ public class CityGmlParser {
 
     private static final SAXParserFactory FACTORY;
 
+    private static Proj4FileReader csReader = new Proj4FileReader();
+    private static final Pattern P_VUNITS = Pattern.compile("^\\+vunits=.+");
+    private static final Pattern P_GEOIDGRID = Pattern.compile("^\\+geoidgrid=.+");
+
     private static CityGMLContext context;
     private static List<QName> chunkProperties = new ArrayList<>();
 
@@ -541,6 +547,10 @@ public class CityGmlParser {
         } catch (Exception e) {
             logEpsgParseError(e);
         }
+        if (handler.getEpsg() == null && logger.isWarnEnabled()) {
+            logger.warn(Localization.getText("CityGmlParser.missingEPSGCode"));
+        }
+
     }
 
     private static void parseEpsgCodeFromBuffer(byte[] buffer, ParserConfiguration config)
@@ -565,6 +575,9 @@ public class CityGmlParser {
         } catch (Exception e) {
             logEpsgParseError(e);
         }
+        if (handler.getEpsg() == null && logger.isWarnEnabled()) {
+            logger.warn(Localization.getText("CityGmlParser.missingEPSGCode"));
+        }
     }
 
     private static void logEpsgParseError(Exception e) {
@@ -576,9 +589,6 @@ public class CityGmlParser {
 
     private static void parseCoordinateSystem(ParserConfiguration config, CityGmlHandler handler) {
         if (handler.getEpsg() == null) {
-            if (logger.isWarnEnabled()) {
-                logger.warn(Localization.getText("CityGmlParser.missingEPSGCode"));
-            }
             return;
         }
         CoordinateReferenceSystem crs = crsFromSrsName(handler.getEpsg());
@@ -671,11 +681,12 @@ public class CityGmlParser {
 
         Matcher mOGC = P_OGC.matcher(srsName);
         if (mOGC.find()) {
-            return CRS_FACTORY.createFromName("EPSG:" + mOGC.group(1));
+            return getCrsFromOGCSrsCode(mOGC.group(1));
         }
         Matcher mOGC2 = P_OGC2.matcher(srsName);
         if (mOGC2.find()) {
-            return CRS_FACTORY.createFromName("EPSG:" + mOGC2.group(1));
+            return getCrsFromOGCSrsCode(mOGC2.group(1));
+
         }
         Matcher mURN = P_URN.matcher(srsName);
         // NOTE: Could use a HashMap if the switch/case becomes too long.
@@ -695,6 +706,14 @@ public class CityGmlParser {
         return null;
     }
 
+    private static CoordinateReferenceSystem getCrsFromOGCSrsCode(String srsCode) {
+        String crsName = "EPSG:" + srsCode;
+        List<String> params = new ArrayList<>(Arrays.stream(csReader.getParameters(crsName)).toList());
+        params.removeIf(P_VUNITS.asPredicate());
+        params.removeIf(P_GEOIDGRID.asPredicate());
+        return CRS_FACTORY.createFromParameters(crsName, params.toArray(new String[0]));
+    }
+
     private static List<String> validateFile(CityGMLContext context, GMLValidationHandler handler, Path file)
             throws CityGmlParseException {
         if (handler == null) {
-- 
GitLab