
// ClosestPoints.java
// Martin Davis
// The LocationTech Technology (LTT) Group; Vivid Solutions
// https://github.com/locationtech/jts
// Modified by Andrew Davison, ad@coe.psu.ac.th, March 2023

/* Computing distance and closest points between geometries using DistanceOp.

   Usage:
    > compile ClosestPoints.java
    > run ClosestPoints

  There are seven examples.
  For each example, the shortest distance is drawn as a line after a 
  brief pause. When prompted, press <enter> on the command line to move 
  to the next example.
*/


import org.locationtech.jts.geom.*;
import org.locationtech.jts.io.*;
import org.locationtech.jts.operation.distance.DistanceOp;



public class ClosestPoints
{
  private static GeometryFactory gf = new GeometryFactory();
  private static GeomsViewer gv;
  private static int count = 0;


  public static void main(String[] args)
  {
    gv = Utils.view("Closest Points");

    findClosestPoint(
      "POLYGON ((200 180, 60 140, 60 260, 200 180))",
      "POINT (140 280)");

    findClosestPoint(
      "POLYGON ((200 180, 60 140, 60 260, 200 180))",
      "MULTIPOINT (140 280, 140 320)");

    findClosestPoint(
      "LINESTRING (100 100, 200 100, 200 200, 100 200, 100 100)",
      "POINT (10 10)");

    findClosestPoint(
      "LINESTRING (100 100, 200 200)",
      "LINESTRING (100 200, 200 100)");

    findClosestPoint(
      "LINESTRING (100 100, 200 200)",
      "LINESTRING (150 121, 200 0)");

    findClosestPoint(
      "POLYGON (( 76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185 ), ( 267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237 ))",
      "LINESTRING ( 153 204, 185 224, 209 207, 238 222, 254 186 )");

    findClosestPoint(
      "POLYGON (( 76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185 ), ( 267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237 ))",
      "LINESTRING ( 120 215, 185 224, 209 207, 238 222, 254 186 )");

    gv.close();
  } /* main */



  private static void findClosestPoint(String wkt1, String wkt2)
  {
    gv.clear();
    count++;
    System.out.println("------ " + count + " ------");
    gv.setTitle(""+count);

    Geometry g1 = Utils.toGeometry(wkt1);
    Geometry g2 = Utils.toGeometry(wkt2);
    System.out.println("Geometry 1: " + g1);
    System.out.println("Geometry 2: " + g2);
    gv.add(g1);
    gv.add(g2);

    Utils.pause(1000);
    DistanceOp distOp = new DistanceOp(g1, g2);
    System.out.printf("Dist: %.2f\n", distOp.distance());

    Coordinate[] coords = distOp.nearestPoints();
    LineString closestPtLine = gf.createLineString(coords);
    System.out.println("Closest points: " + Utils.simplify(closestPtLine));
    gv.add("close", closestPtLine);
    System.out.printf("Dist: %.2f\n", closestPtLine.getLength());
    Utils.waitEnter();

  } /* findClosestPoint */


}  // end of ClosestPoints class
