[ 
https://issues.apache.org/jira/browse/TINKERPOP-2558?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18143990#comment-18143990
 ] 

ASF GitHub Bot commented on TINKERPOP-2558:
-------------------------------------------

GumpacG commented on code in PR #3754:
URL: https://github.com/apache/tinkerpop/pull/3754#discussion_r4555623126


##########
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/geo/WktReader.java:
##########
@@ -0,0 +1,621 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.geo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Package-private WKT/EWKT parser.
+ */
+final class WktReader {
+
+    /**
+     * Longest run of input echoed back in an exception message.
+     */
+    private static final int MAX_ECHOED_INPUT = 64;
+
+    /**
+     * Longest run of SRID digits accepted after an EWKT "SRID=" prefix.
+     */
+    private static final int MAX_SRID_DIGITS = 10;
+
+    private final String input;
+    private int pos;
+    private int depth; // collection nesting depth
+    private int srid;
+    private Boolean hasZ; // null = not yet determined
+
+    private WktReader(final String input) {
+        this.input = input;
+        this.pos = 0;
+        this.depth = 0;
+    }
+
+    /**
+     * Parses WKT or EWKT text.
+     *
+     * @param wktOrEwkt the input text
+     * @param model explicit model, or null to derive from EWKT prefix
+     * @param srid explicit SRID, or null to derive from EWKT prefix
+     * @return the parsed geometry
+     */
+    static Geometry parse(final String wktOrEwkt, final Model model, final 
Integer srid) {
+        if (wktOrEwkt == null || wktOrEwkt.trim().isEmpty()) {
+            throw new IllegalArgumentException("WKT input cannot be null or 
empty");
+        }
+
+        final WktReader reader = new WktReader(wktOrEwkt);
+        reader.skipWhitespace();
+
+        // Check for EWKT prefix
+        Integer ewktSrid = null;
+        if (reader.matchExact("SRID=")) {
+            ewktSrid = reader.parseSrid();
+            reader.expect(';');
+            reader.skipWhitespace();
+        }
+
+        // Determine final SRID
+        if (ewktSrid != null && srid != null && !ewktSrid.equals(srid)) {
+            throw new IllegalArgumentException("EWKT SRID " + ewktSrid + " 
conflicts with argument SRID " + srid);
+        }
+        if (ewktSrid != null && model != null) {
+            final int modelSrid = CoordinateValidator.sridForModel(model);
+            if (!ewktSrid.equals(modelSrid)) {
+                throw new IllegalArgumentException("EWKT SRID " + ewktSrid + " 
conflicts with model " + model);
+            }
+        }
+
+        final int finalSrid;
+        if (srid != null) {
+            finalSrid = srid;
+        } else if (ewktSrid != null) {
+            finalSrid = ewktSrid;
+        } else if (model != null) {
+            finalSrid = CoordinateValidator.sridForModel(model);
+        } else {
+            finalSrid = CoordinateValidator.SRID_CARTESIAN;
+        }
+
+        reader.srid = finalSrid;
+
+        // Parse geometry
+        final Geometry g = reader.parseGeometry();
+
+        // Check for trailing text
+        reader.skipWhitespace();
+        if (reader.pos < reader.input.length()) {
+            throw new IllegalArgumentException("Unexpected trailing text: " + 
truncate(reader.input.substring(reader.pos)));
+        }
+
+        return g;
+    }
+
+    private Geometry parseGeometry() {
+        skipWhitespace();
+
+        if (matchIgnoreCase("POINT")) {
+            return parsePoint();
+        } else if (matchIgnoreCase("LINESTRING")) {
+            return parseLineString();
+        } else if (matchIgnoreCase("POLYGON")) {
+            return parsePolygon();
+        } else if (matchIgnoreCase("MULTIPOINT")) {
+            return parseMultiPoint();
+        } else if (matchIgnoreCase("MULTILINESTRING")) {
+            return parseMultiLineString();
+        } else if (matchIgnoreCase("MULTIPOLYGON")) {
+            return parseMultiPolygon();
+        } else if (matchIgnoreCase("GEOMETRYCOLLECTION")) {
+            return parseGeometryCollection();
+        } else {
+            // Check for unsupported types
+            if (matchIgnoreCase("CIRCULARSTRING") || 
matchIgnoreCase("COMPOUNDCURVE") ||
+                matchIgnoreCase("CURVEPOLYGON") || 
matchIgnoreCase("MULTICURVE") ||
+                matchIgnoreCase("MULTISURFACE") || matchIgnoreCase("TRIANGLE") 
||
+                matchIgnoreCase("TIN") || 
matchIgnoreCase("POLYHEDRALSURFACE")) {
+                throw new IllegalArgumentException("Unsupported geometry 
type");
+            }
+            throw new IllegalArgumentException("Unknown geometry type at 
position " + pos);
+        }
+    }
+
+    private Point parsePoint() {
+        final boolean z = parseZTag();
+        skipWhitespace();
+
+        if (matchIgnoreCase("EMPTY")) {
+            recordZTag(z);
+            return Point.emptyWithZ(srid, z);
+        }
+
+        expect('(');
+        final Point p = parseCoordinate(z);
+        expect(')');
+
+        recordZTag(z);
+        return p;
+    }
+
+    /**
+     * Parses one coordinate, "x y" or "x y z", into a point.
+     */
+    private Point parseCoordinate(final boolean z) {
+        skipWhitespace();
+        final double x = parseNumber();
+        skipWhitespace();
+        final double y = parseNumber();
+        skipWhitespace();
+
+        if (z) {
+            final double zVal = parseNumber();
+            skipWhitespace();
+            return Point.ofWithSrid(x, y, zVal, srid);
+        }
+
+        // A further ordinate without a Z tag is malformed
+        if (startsNumber(peek())) {
+            throw new IllegalArgumentException("Coordinate has 3 ordinates but 
no Z tag");

Review Comment:
   This is intentional in order to make it explicit that it is a 3D coordinate. 
If there is demand for this case, it can be added without breaking change in 
4.x.





> GEO Spatial APIs
> ----------------
>
>                 Key: TINKERPOP-2558
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2558
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: process
>    Affects Versions: 3.5.0
>            Reporter: Jitesh
>            Priority: Major
>
> Provide support for Geo based APIs (predicates, objects, etc)
>  
>  



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to