View Javadoc
1   package au.gov.amsa.geo;
2   
3   import com.github.davidmoten.grumpy.core.Position;
4   import com.vividsolutions.jts.geom.Coordinate;
5   import com.vividsolutions.jts.geom.Geometry;
6   import com.vividsolutions.jts.geom.GeometryFactory;
7   import com.vividsolutions.jts.geom.LineString;
8   import com.vividsolutions.jts.geom.prep.PreparedGeometry;
9   
10  import au.gov.amsa.gt.Shapefile;
11  import au.gov.amsa.risky.format.Fix;
12  
13  public class ShapefileUtil {
14      
15      public static TimedPosition findRegionCrossingPoint(Shapefile region, Fix fix1, Fix fix2) {
16  
17          Coordinate[] coords = new Coordinate[] { new Coordinate(fix1.lon(), fix1.lat()),
18                  new Coordinate(fix2.lon(), fix2.lat()) };
19          LineString line = new GeometryFactory().createLineString(coords);
20          for (PreparedGeometry g : region.geometries()) {
21              if (g.crosses(line)) {
22                  Geometry intersection = g.getGeometry().intersection(line);
23                  // expecting just one point
24                  Coordinate coord = intersection.getCoordinate();
25                  double longitude = coord.x;
26                  double latitude = coord.y;
27                  Position a = Position.create(fix1.lat(), fix1.lon());
28                  Position b = Position.create(fix2.lat(), fix2.lon());
29                  Position c = Position.create(latitude, longitude);
30                  double ac = a.getDistanceToKm(c);
31                  double bc = b.getDistanceToKm(c);
32                  if (ac == 0) {
33                      return new TimedPosition(fix1.lat(), fix1.lon(), fix1.time());
34                  } else if (bc == 0) {
35                      return new TimedPosition(fix2.lat(), fix2.lon(), fix2.time());
36                  } else {
37                      // predict the timestamp based on distance from a and b
38                      long diff = fix2.time() - fix1.time();
39                      long t = Math.round(fix1.time() + ac * diff / (ac + bc));
40                      return new TimedPosition(latitude, longitude, t);
41                  }
42              }
43          }
44          throw new RuntimeException("crossing not found");
45      }
46  
47  }