Package chunmap.model.relate

Source Code of chunmap.model.relate.ComputeIm

/**
* 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;

import chunmap.model.elem.Envelope;
import chunmap.model.geom.*;
import static chunmap.model.relate.IntersectionMatrix.*;

/**
* 计算两个几何体之间的关系
*
* @author chunquedong
*
*/
public abstract class ComputeIm {

  protected Geometry g1;
  protected Geometry g2;
  protected IntersectionMatrix im;
  private boolean isReverse = false;

  /**
   * 返回IM
   *
   * @return
   */
  public IntersectionMatrix getIM() {
    if (im == null) {
      if (!g1.isValid() || !g2.isValid()) {
        throw new GeometryException();
      }
      im = new IntersectionMatrix();
      im.set(Outer, Outer, AreaDim);
      computeIM();
      // 转置
      if (isReverse) {
        im = im.reverse();
      }
    }
    return im;
  }

  /**
   * 对调两个几何体顺序的IM
   *
   * @return
   */
  protected ComputeIm setReverse(boolean b) {
    isReverse = b;
    return this;
  }

  // ------------------------------------------------------------主函数

  /**
   * 计算IM的模板,主要方法。次方法也可能被子类覆盖以提高效率
   */
  protected void computeIM() {
    Envelope en1 = g1.getEnvelop();
    boolean hasInte = en1.hasIntersect(g2.getEnvelop());
    if (!hasInte) {
      // 相离时
      disjoin();
    } else {
      // 设置边界
      setBorderIM();
      // 设置内部
      int iiDim = inner2innerDim(g1, g2);
      im.set(Inner, Inner, iiDim);
      // 设置内外,外内
      setInnerOuterAndOuterInner();
    }
  }

  // ------------------------------------------------------------辅助函数

  /**
   * 设置内外,外内
   *
   */
  private void setInnerOuterAndOuterInner() {
    int dim1 = g1.getGeometryType().dimension();
    int dim2 = g2.getGeometryType().dimension();

    if (dim1 < dim2) {
      setInnerOuter();
      im.set(Outer, Inner, dim2);
    } else if (dim1 > dim2) {
      im.set(Inner, Outer, dim1);
      setOuterInner();
    } else {
      setInnerOuter();
      setOuterInner();
    }
  }

  private void setInnerOuter() {
    if (isDisjoin()) {
      im.set(Inner, Outer, getBoundaryDimension(g1));
    } else if (within(g1, g2)) {
      im.set(Inner, Outer, EmptyDim);
    } else {
      im.set(Inner, Outer, getBoundaryDimension(g1));
    }
  }

  /**
   * @return
   */
  private boolean isDisjoin() {
    return im.get(Inner, Inner) == EmptyDim
        && im.get(Inner, Border) == EmptyDim;
  }

  private void setOuterInner() {
    if (isDisjoin()) {
      im.set(Inner, Outer, getBoundaryDimension(g1));
    } else if (within(g2, g1)) {
      im.set(Outer, Inner, EmptyDim);
    } else {
      im.set(Outer, Inner, getBoundaryDimension(g2));
    }
  }

  // ------------------------------------------------------------钩子方法
  //
  /**
   * 内部和内部的交集维度。计算时可参考边界交集。
   *
   * @param g1
   * @param g2
   * @return
   */
  protected abstract int inner2innerDim(Geometry g1, Geometry g2);

  //
  /**
   * 是否完全被包含在里面。计算时可参考IIDim,但相同维度计算不可使用边界交集。
   *
   * @param g1
   * @param g2
   * @return
   */
  protected abstract boolean within(Geometry g1, Geometry g2);

  // ------------------------------------------------------------相离时

  /**
   * 相离时设置IM
   */
  private void disjoin() {
    im.set(Outer, Inner, g2.getGeometryType().dimension());
    im.set(Inner, Outer, g1.getGeometryType().dimension());

    int bdim1 = getBoundaryDimension(g1);
    int bdim2 = getBoundaryDimension(g2);

    im.set(Outer, Border, bdim2);
    im.set(Border, Outer, bdim1);
  }

  /**
   * 边界维度
   *
   * @return
   */
  private int getBoundaryDimension(Geometry g) {
    Geometry b1 = g.getBoundary();
    int bdim1 = (b1 == null) ? -1 : b1.getGeometryType().dimension();
    return bdim1;
  }

  // ------------------------------------------------------------设置边界

  /**
   * 设置边界处的IM
   */
  private void setBorderIM() {
    Geometry b2 = g2.getBoundary();
    if (b2 != null) {
      IntersectionMatrix tim = ComputeImFactory.getInstance()
          .getImComputer(g1, b2).getIM();
      im.set(Inner, Border, getDim(tim, Inner));
      im.set(Border, Border, getDim(tim, Border));
      im.set(Outer, Border, getDim(tim, Outer));
    }

    Geometry b1 = g1.getBoundary();
    if (b1 != null) {
      IntersectionMatrix tim = ComputeImFactory.getInstance()
          .getImComputer(b1, g2).getIM();
      im.set(Border, Inner, getDim2(tim, Inner));
      im.set(Border, Border, getDim2(tim, Border));
      im.set(Border, Outer, getDim2(tim, Outer));
    }
  }

  private int getDim(IntersectionMatrix tim, int i) {
    int ii = tim.get(i, Inner);
    int ib = tim.get(i, Border);

    return Math.max(ii, ib);
  }

  private int getDim2(IntersectionMatrix tim, int i) {
    int ii = tim.get(Inner, i);
    int ib = tim.get(Border, i);

    return Math.max(ii, ib);
  }

}
TOP

Related Classes of chunmap.model.relate.ComputeIm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.