MultiPoint2DFunctions.java

  1. /*
  2.  * Copyright 2015 gregory.graham.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package nz.co.gregs.dbvolution.internal.sqlite;

  17. import java.sql.Connection;
  18. import java.sql.SQLException;
  19. import com.vividsolutions.jts.geom.*;
  20. import com.vividsolutions.jts.io.ParseException;
  21. import com.vividsolutions.jts.io.WKTReader;
  22. import org.sqlite.Function;

  23. /**
  24.  *
  25.  * @author gregory.graham
  26.  */
  27. public class MultiPoint2DFunctions {

  28.     /**
  29.      *
  30.      */
  31.     public final static String CREATE_FROM_COORDS_FUNCTION = "DBV_CREATE_MPOINT2D_FROM_COORDS";

  32.     /**
  33.      *
  34.      */
  35.     public final static String EQUALS_FUNCTION = "DBV_MPOINT2D_EQUALS";

  36.     /**
  37.      *
  38.      */
  39.     public final static String GETMAXX_FUNCTION = "DBV_MPOINT2D_GETMAXX";

  40.     /**
  41.      *
  42.      */
  43.     public final static String GETMAXY_FUNCTION = "DBV_MPOINT2D_GETMAXY";

  44.     /**
  45.      *
  46.      */
  47.     public final static String GETMINX_FUNCTION = "DBV_MPOINT2D_GETMINX";

  48.     /**
  49.      *
  50.      */
  51.     public final static String GETMINY_FUNCTION = "DBV_MPOINT2D_GETMINY";

  52.     /**
  53.      *
  54.      */
  55.     public final static String GETDIMENSION_FUNCTION = "DBV_MPOINT2D_GETDIMENSION";

  56.     /**
  57.      *
  58.      */
  59.     public final static String GETBOUNDINGBOX_FUNCTION = "DBV_MPOINT2D_GETBOUNDINGBOX";

  60.     /**
  61.      *
  62.      */
  63.     public final static String GETNUMBEROFPOINTS_FUNCTION = "DBV_MPOINT2D_GETNUMBEROFPOINTS";

  64.     /**
  65.      *
  66.      */
  67.     public final static String GETPOINTATINDEX_FUNCTION = "DBV_MPOINT2D_GETPOINTATINDEX";

  68.     /**
  69.      *
  70.      */
  71.     public final static String ASTEXT_FUNCTION = "DBV_MPOINT2D_ASTEXT";

  72.     /**
  73.      *
  74.      */
  75.     public final static String ASLINE2D = "DBV_MPOINT2D_ASLINE2D";

  76.     private MultiPoint2DFunctions() {
  77.     }

  78.     /**
  79.      *
  80.      * @param connection the connection that needs functions added
  81.      * @throws SQLException database errors
  82.      */
  83.     public static void addFunctions(Connection connection) throws SQLException {
  84.         Function.create(connection, CREATE_FROM_COORDS_FUNCTION, new CreateFromCoords());
  85.         Function.create(connection, EQUALS_FUNCTION, new Equals());
  86.         Function.create(connection, GETMAXX_FUNCTION, new GetMaxX());
  87.         Function.create(connection, GETMAXY_FUNCTION, new GetMaxY());
  88.         Function.create(connection, GETMINX_FUNCTION, new GetMinX());
  89.         Function.create(connection, GETMINY_FUNCTION, new GetMinY());
  90.         Function.create(connection, GETDIMENSION_FUNCTION, new GetDimension());
  91.         Function.create(connection, GETBOUNDINGBOX_FUNCTION, new GetBoundingBox());
  92.         Function.create(connection, GETNUMBEROFPOINTS_FUNCTION, new GetNumberOfPoints());
  93.         Function.create(connection, GETPOINTATINDEX_FUNCTION, new GetPointAtIndex());
  94.         Function.create(connection, ASTEXT_FUNCTION, new AsText());
  95.         Function.create(connection, ASLINE2D, new AsLine2D());
  96. //      Function.create(connection, ASPOLYGON2D, new AsPolygon2D());
  97.     }

  98.     private static class CreateFromCoords extends PolygonFunction {
  99. //MULTIPOINT (2 3, 3 4)

  100.         @Override
  101.         protected void xFunc() throws SQLException {
  102.             Integer numberOfArguments = args();
  103.             if (numberOfArguments == 0) {
  104.                 result();
  105.             } else {
  106.                 StringBuilder resultStr = new StringBuilder("MULTIPOINT (");
  107.                 String sep = "";
  108.                 for (int i = 0; i < numberOfArguments; i += 2) {
  109.                     Double x = value_double(i);
  110.                     Double y = value_double(i + 1);
  111.                     resultStr.append(sep).append(x).append(" ").append(y);
  112.                     sep = ", ";
  113.                 }
  114.                 resultStr.append(")");
  115.                 result(resultStr.toString());
  116.             }
  117.         }
  118.     }

  119.     private static class GetNumberOfPoints extends PolygonFunction {
  120. //'MULTIPOINT ((2 3), (3 4), (4 5))'

  121.         @Override
  122.         protected void xFunc() throws SQLException {
  123.             String multipoint = value_text(0);
  124.             if (multipoint == null || multipoint.equals("")) {
  125.                 result();
  126.             } else {
  127.                 Double maxX = null;
  128.                 String[] split = multipoint.trim().split("[ (),]+");
  129.                 result((split.length - 1) / 2);
  130.             }
  131.         }
  132.     }

  133.     private static class GetPointAtIndex extends PolygonFunction {
  134. //MULTIPOINT (2 3, 3 4)

  135.         @Override
  136.         protected void xFunc() throws SQLException {
  137.             String multipoint = value_text(0);
  138.             int index = value_int(1);
  139.             final int indexInMPoint = index * 2;
  140.             if (multipoint == null || indexInMPoint <= 0) {
  141.                 result();
  142.             } else {
  143.                 String[] split = multipoint.split("[ (),]+");
  144.                 if (indexInMPoint > split.length) {
  145.                     result();
  146.                 } else {
  147.                     String x = split[indexInMPoint - 1];
  148.                     String y = split[indexInMPoint];
  149.                     result("POINT (" + x + " " + y + ")");
  150.                 }
  151.             }
  152.         }
  153.     }

  154.     private static class Equals extends PolygonFunction {

  155.         @Override
  156.         protected void xFunc() throws SQLException {
  157.             String firstMPoint = value_text(0);
  158.             String secondMPoint = value_text(1);
  159.             if (firstMPoint == null || secondMPoint == null) {
  160.                 result();
  161.             } else {
  162.                 result(firstMPoint.equals(secondMPoint) ? 1 : 0);
  163.             }
  164.         }
  165.     }

  166.     private static class GetMaxX extends PolygonFunction {

  167.         @Override
  168.         protected void xFunc() throws SQLException {
  169.             String multipoint = value_text(0);
  170.             if (multipoint == null) {
  171.                 result();
  172.             } else {
  173.                 Double maxX = null;
  174.                 String[] split = multipoint.split("[ (),]+");
  175.                 for (int i = 1; i < split.length; i += 2) {
  176.                     double x = Double.parseDouble(split[i]);
  177. //                  double y = Double.parseDouble(split[i + 1]);
  178.                     if (maxX == null || maxX < x) {
  179.                         maxX = x;
  180.                     }
  181.                 }
  182.                 result(maxX);
  183.             }
  184.         }

  185.     }

  186.     private static class GetMaxY extends PolygonFunction {

  187.         @Override
  188.         protected void xFunc() throws SQLException {
  189.             String multipoint = value_text(0);
  190.             if (multipoint == null) {
  191.                 result();
  192.             } else {
  193.                 Double maxY = null;
  194.                 String[] split = multipoint.split("[ (),]+");
  195.                 for (int i = 1; i < split.length; i += 2) {
  196. //                  double x = Double.parseDouble(split[i]);
  197.                     double y = Double.parseDouble(split[i + 1]);
  198.                     if (maxY == null || maxY < y) {
  199.                         maxY = y;
  200.                     }
  201.                 }
  202.                 result(maxY);
  203.             }
  204.         }
  205.     }

  206.     private static class GetMinX extends PolygonFunction {

  207.         @Override
  208.         protected void xFunc() throws SQLException {
  209.             String multipoint = value_text(0);
  210.             if (multipoint == null) {
  211.                 result();
  212.             } else {
  213.                 Double minX = null;
  214.                 String[] split = multipoint.split("[ (),]+");
  215.                 for (int i = 1; i < split.length; i += 2) {
  216.                     double x = Double.parseDouble(split[i]);
  217. //                  double y = Double.parseDouble(split[i + 1]);
  218.                     if (minX == null || minX > x) {
  219.                         minX = x;
  220.                     }
  221.                 }
  222.                 result(minX);
  223.             }
  224.         }

  225.     }

  226.     private static class GetMinY extends PolygonFunction {

  227.         @Override
  228.         protected void xFunc() throws SQLException {
  229.             String multipoint = value_text(0);
  230.             if (multipoint == null) {
  231.                 result();
  232.             } else {
  233.                 Double minY = null;
  234.                 String[] split = multipoint.split("[ (),]+");
  235.                 for (int i = 1; i < split.length; i += 2) {
  236. //                  double x = Double.parseDouble(split[i]);
  237.                     double y = Double.parseDouble(split[i + 1]);
  238.                     if (minY == null || minY > y) {
  239.                         minY = y;
  240.                     }
  241.                 }
  242.                 result(minY);
  243.             }
  244.         }
  245.     }

  246.     private static class GetDimension extends PolygonFunction {

  247.         @Override
  248.         protected void xFunc() throws SQLException {
  249.             result(0);
  250.         }
  251.     }

  252.     private static class GetBoundingBox extends PolygonFunction {

  253.         @Override
  254.         protected void xFunc() throws SQLException {
  255.             String multipoint = value_text(0);
  256.             if (multipoint == null) {
  257.                 result();
  258.             } else {
  259.                 Double maxX = null;
  260.                 Double maxY = null;
  261.                 Double minX = null;
  262.                 Double minY = null;
  263.                 String[] split = multipoint.split("[ (),]+");
  264.                 for (int i = 1; i < split.length; i += 2) {
  265.                     double x = Double.parseDouble(split[i]);
  266.                     double y = Double.parseDouble(split[i + 1]);
  267.                     if (maxX == null || maxX < x) {
  268.                         maxX = x;
  269.                     }
  270.                     if (maxY == null || maxY < y) {
  271.                         maxY = y;
  272.                     }
  273.                     if (minX == null || minX > x) {
  274.                         minX = x;
  275.                     }
  276.                     if (minY == null || minY > y) {
  277.                         minY = y;
  278.                     }
  279.                 }
  280.                 String resultString = "POLYGON ((" + minX + " " + minY + ", " + maxX + " " + minY + ", " + maxX + " " + maxY + ", " + minX + " " + maxY + ", " + minX + " " + minY + "))";
  281.                 result(resultString);
  282.             }
  283.         }
  284.     }

  285.     private static class AsText extends Function {

  286.         @Override
  287.         protected void xFunc() throws SQLException {
  288.             String multipoint = value_text(0);
  289.             result(multipoint);
  290.         }
  291.     }

  292.     private static class AsLine2D extends Function {

  293.         @Override
  294.         protected void xFunc() throws SQLException {
  295.             if(value_text(0)==null){
  296.                 result();
  297.                 return;
  298.             }
  299.             String multipoint = value_text(0);
  300.             String line = multipoint.replace("), (", ", ").replace("MULTIPOINT", "LINESTRING").replace("((", "(").replace("))", ")");
  301.             result(line);
  302.         }
  303.     }

  304.     private static abstract class PolygonFunction extends Function {

  305.         Polygon getPolygon(String possiblePoly) throws ParseException {
  306.             WKTReader wktReader = new WKTReader();
  307.             Geometry firstGeom = wktReader.read(possiblePoly);
  308.             if (firstGeom instanceof Polygon) {
  309.                 return (Polygon) firstGeom;
  310.             }
  311.             return null;
  312.         }

  313.         LineString getLineString(String possiblePoly) throws ParseException {
  314.             WKTReader wktReader = new WKTReader();
  315.             Geometry firstGeom = wktReader.read(possiblePoly);
  316.             if (firstGeom instanceof LineString) {
  317.                 return (LineString) firstGeom;
  318.             }
  319.             return null;
  320.         }

  321.         Point getPoint(String possiblePoly) throws ParseException {
  322.             WKTReader wktReader = new WKTReader();
  323.             Geometry firstGeom = wktReader.read(possiblePoly);
  324.             if (firstGeom instanceof Point) {
  325.                 return (Point) firstGeom;
  326.             }
  327.             return null;
  328.         }

  329.         MultiPoint getMultiPoint(String possiblePoly) throws ParseException {
  330.             WKTReader wktReader = new WKTReader();
  331.             Geometry firstGeom = wktReader.read(possiblePoly);
  332.             if (firstGeom instanceof MultiPoint) {
  333.                 return (MultiPoint) firstGeom;
  334.             }
  335.             return null;
  336.         }
  337.     }

  338. }