/**
* Copyright (c) 2009-2011, chunquedong(YangJiandong)
*
* This file is part of ChunMap project
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
*
* History:
* 2010-05-05 Jed Young Creation
*/
package chunmap.model.relate.relateop;
import static chunmap.model.relate.IntersectionMatrix.*;
import chunmap.model.coord.CoordSeqEditor;
import chunmap.model.coord.CPoint;
import chunmap.model.elem.LineSegment;
import chunmap.model.geom.Geometry;
import chunmap.model.geom.LineString;
import chunmap.model.geom.Ring;
import chunmap.model.geom.Polygon;
import chunmap.model.relate.ComputeIm;
/**
* disjion,touch,over,within,onBoundary
*
* @author chunquedong
*
*/
class LineString_LinearRing extends ComputeIm {
public LineString_LinearRing(LineString l1, Ring r2) {
g1 = l1;
g2 = r2.toPolygon();
}
private boolean cross = false;// 是否有交叉
private boolean within = false;// 被包含
@Override
protected int inner2innerDim(Geometry g1, Geometry g2) {
LineString l1 = (LineString) g1;
Ring r2 = ((Polygon) g2).getShell();
// 线和环边界分离
if (im.get(Inner, Border) == EmptyDim
&& im.get(Border, Border) == EmptyDim) {
if (r2.containIn(l1.firstPoint())) {
within = true;
return LineDim;
}
return EmptyDim;
}
// 是否有十字交叉
if (_hasCross(r2,l1)) {
cross = true;
return LineDim;
}
// 用自己的折点将线串打断
CoordSeqEditor tLine = new CoordSeqEditor(l1.getPoints());
for (int i = 0, n = r2.size(); i < n; i++) {
CPoint p = r2.getPoint(i);
tLine.tryInsertPoint(p);
}
// 片段在里面
for (int i = 0, n = tLine.size() - 1; i < n; i++) {
LineSegment lseg = tLine.getLineSegment(i);
CPoint mp = lseg.getMiddlePoint();
if (r2.containIn(mp) && !r2.onLineString(mp)) {
return LineDim;
}
}
return EmptyDim;
}
@Override
protected boolean within(Geometry g1, Geometry g2) {
if (within)
return true;
if (cross)
return false;
LineString l1 = (LineString) g1;
Ring r2 = ((Polygon) g2).getShell();
if (r2.containLineStringIn(l1))
return true;
return false;
}
public boolean _hasCross(LineString me,LineString l1) {
LineString l2 = me;
for (int i = 0, n = l1.size() - 1; i < n; i++) {
for (int j = 0, n2 = l2.size() - 1; j < n2; j++) {
LineSegment s1 = l1.getLineSegment(i);
LineSegment s2 = l2.getLineSegment(j);
Object g = s1.intersection(s2);
if (g == null) {
continue;
} else if (g instanceof CPoint) {
CPoint p = (CPoint) g;
if (!isSegmentBorder(s1, s2, p)) {
return true;
}
}
}
}
return false;
}
// 鏄竟鐣岀偣
private boolean isSegmentBorder(LineSegment l1, LineSegment l2, CPoint p) {
return p.approximateEquals(l1.getStartPoint())
|| p.approximateEquals(l1.getEndPoint())
|| p.approximateEquals(l2.getStartPoint())
|| p.approximateEquals(l2.getEndPoint());
}
}