Package chunmap.model.geom

Source Code of chunmap.model.geom.Polygon

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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import chunmap.model.coord.Transform;
import chunmap.model.elem.Envelope;
import chunmap.model.elem.PointLineBag;
import chunmap.model.relate.ComputeIm;
import chunmap.model.relate.IntersectionMatrix;
import chunmap.model.relate.relateop.Polygon_Polygon;

/**
* @author chunquedong
*
*/
public class Polygon extends AbstractGeometry implements Iterable<Ring> {

  private final Ring shell;
  private final List<Ring> holes;

  /**
   * @param shell
   * @param holes
   */
  public Polygon(Ring shell, List<Ring> holes) {
    if (shell == null) {
      throw new NullPointerException();
    }
    this.shell = shell;
   
    List<Ring> newHoles = new ArrayList<Ring>();
    if (holes != null) {
      for (Ring r : holes) {
        newHoles.add(r);
      }
    }
    this.holes = newHoles;
  }

  public Polygon(Ring shell) {
    this(shell, null);
  }

  public Ring getShell() {
    return shell;
  }

  public List<Ring> getHoles() {
    List<Ring> newHoles = new ArrayList<Ring>();
    for (Ring r : holes) {
      newHoles.add(r);
    }
    return newHoles;
  }

  public int ringCount() {
    return holes.size() + 1;
  }

  @Override
  protected Envelope calculateEnvelop() {
    return shell.getEnvelop();
  }

  @Override
  public GeometryType getGeometryType() {
    return GeometryType.Polygon;
  }

  @Override
  public String toString() {
    return "POLYGON" + toMyString();
  }

  public String toMyString() {
    StringBuilder str = new StringBuilder();
    str.append("(");
    str.append(shell.toMyString());
    for (Ring g : holes) {
      str.append("," + g.toMyString());
    }
    str.append(")");
    return str.toString();
  }

  @Override
  public Geometry getBoundary() {
    List<LineString> bs = new ArrayList<LineString>();
    bs.add(shell);
    bs.addAll(holes);

    return new MultiLineString(bs);
  }

  @Override
  protected boolean isSimple() {
    if (!shell.isValid())
      return false;
    for (Ring r : holes) {
      if (!r.isValid()) {
        return false;
      }
    }
    for (Ring r : holes) {
      if (!shell.containLineStringIn(r)) {
        return false;
      }
    }
    for (int i = 0, n = holes.size(); i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        Ring r1 = holes.get(i);
        Ring r2 = holes.get(i);
        ComputeIm ac = new Polygon_Polygon(r1.toPolygon(), r2
            .toPolygon());
        if (ac.getIM().get(IntersectionMatrix.Inner,
            IntersectionMatrix.Inner) != IntersectionMatrix.EmptyDim) {
          return false;
        }
      }
    }
    return true;
  }

  @Override
  public GeometryCollection toGeometryCollection() {
    List<Polygon> gs = new ArrayList<Polygon>();
    gs.add(this);
    return new MultiPolygon(gs);
  }

  @Override
  public Geometry transform(Transform transf) {
    Ring lr = ((LineString) (shell.transform(transf))).toLinearRing();
    List<Ring> newHoles = new ArrayList<Ring>();
    for (Ring r : holes) {
      Ring newr = (Ring) (r.transform(transf));
      newHoles.add(newr);
    }
    return new Polygon(lr, newHoles);
  }

  public double computeArea() {
    double area = Math.abs(shell.computeArea());
    for (Ring r : holes) {
      double holesA = Math.abs(r.computeArea());
      area -= holesA;
    }
    return area;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((holes == null) ? 0 : holes.hashCode());
    result = prime * result + ((shell == null) ? 0 : shell.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    Polygon other = (Polygon) obj;
    if (holes == null) {
      if (other.holes != null)
        return false;
    } else if (!holes.equals(other.holes))
      return false;
    if (shell == null) {
      if (other.shell != null)
        return false;
    } else if (!shell.equals(other.shell))
      return false;
    return true;
  }

  /**
   * 是否完全落在孔中
   *
   * @param line
   * @return
   */
  public boolean inHoles(LineString line) {
    // 打断
    List<LineString> lines = new ArrayList<LineString>();
    lines.add(line);
    for (Ring r : holes) {
      breakLine(r, lines);
    }

    for (LineString l : lines) {
      if (!this.inOneHoles(l)) {
        return false;
      }
    }
    return true;
  }

  /**
   * 完全落在一个孔里
   *
   * @param line
   * @return
   */
  private boolean inOneHoles(LineString line) {
    for (Ring r : holes) {
      if (r.containLineStringIn(line)) {
        return true;
      }
    }
    return false;
  }

  private void breakLine(Ring r, List<LineString> lines) {
    for (int i = 0, n = lines.size(); i < n; i++) {
      LineString line = lines.get(i);
      PointLineBag bag = line.intersection(r);
      List<LineString> newLines = bag.breakLine(line);
     
      if (newLines.size() > 1) {
        lines.remove(i);
        lines.addAll(newLines);
        return;
      }
    }
  }

  @Override
  public Iterator<Ring> iterator() {
    return new Iterator<Ring>() {
      Iterator<Ring> it = holes.iterator();
      int i = 0;

      @Override
      public boolean hasNext() {
        if (i == 0)
          return true;
        else {
          return it.hasNext();
        }
      }

      @Override
      public Ring next() {
        if (i == 0)
          return shell;
        else
          return it.next();
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException();
      }
    };
  }
}
TOP

Related Classes of chunmap.model.geom.Polygon

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.