Package chunmap.model.operate.overlay

Source Code of chunmap.model.operate.overlay.FragmentCollection

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

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

import chunmap.model.coord.CoordSeqEditor;
import chunmap.model.elem.PointLineBag;
import chunmap.model.geom.GeometryException;
import chunmap.model.geom.LineString;
import chunmap.model.geom.Ring;
import chunmap.model.geom.Polygon;
import chunmap.model.relate.ComputeIm;
import chunmap.model.relate.ComputeImFactory;
import chunmap.model.relate.IntersectionMatrix;

/**
* @author chunquedong
*
*/
public class FragmentCollection {

  private final List<Fragment> fragments1 = new ArrayList<Fragment>();
  private final List<Fragment> fragments2 = new ArrayList<Fragment>();

  public FragmentCollection(Polygon r1, Polygon r2) {
    if (!r1.isValid() || !r2.isValid()) {
      throw new GeometryException();
    }

    PointLineBag bag = getIntersection(r1, r2);

    addPolygon(fragments1, r1, r2, bag);
    addPolygon(fragments2, r2, r1, bag);
  }

  private void addPolygon(List<Fragment> fragment1, Polygon pg,
      Polygon other, PointLineBag bag) {
   
    fillList(fragment1, bag.breakLine(pg.getShell()), other);

    List<Ring> rs = pg.getHoles();
    for (Ring r : rs) {
      fillList(fragment1, bag.breakLine(r), other);
    }
    return;
  }

  private PointLineBag getIntersection(Polygon pg1, Polygon pg2) {
    PointLineBag tbag = subGetIntersection(pg1.getShell(), pg2);
    List<Ring> rs = pg1.getHoles();
    for (Ring r : rs) {
      tbag.add(subGetIntersection(r, pg2));
    }
    return tbag;
  }

  private PointLineBag subGetIntersection(Ring r1, Polygon pg2) {
    PointLineBag tbag = r1.intersection(pg2.getShell());
    List<Ring> rs = pg2.getHoles();
    for (Ring r : rs) {
      tbag.add(r1.intersection(r));
    }
    return tbag;
  }

  private void fillList(List<Fragment> fragment1,
      List<LineString> lineStrings, Polygon other) {

    for (LineString ls : lineStrings) {
      Fragment fra = new Fragment();
      fra.setLineString(ls);

      ComputeIm cim = ComputeImFactory.getInstance().getImComputer(ls,
          other);
      IntersectionMatrix im = cim.getIM();
      boolean isWithin = isWithin(im);
      boolean isBorder = isOnBorder(im);

      if (isBorder) {
        fra.setContainIn(Fragment.Border);
      } else if (isWithin) {
        fra.setContainIn(Fragment.Inner);
      } else {
        fra.setContainIn(Fragment.Outer);
      }
      fragment1.add(fra);
    }
  }

  public boolean isOnBorder(IntersectionMatrix im) {
    boolean b1 = (im.get(IntersectionMatrix.Inner,
        IntersectionMatrix.Border) != IntersectionMatrix.EmptyDim);
    boolean b2 = im.get(IntersectionMatrix.Inner, IntersectionMatrix.Inner) == IntersectionMatrix.EmptyDim;
    boolean b3 = im.get(IntersectionMatrix.Inner, IntersectionMatrix.Outer) == IntersectionMatrix.EmptyDim;

    if (b1 && b2 && b3)
      return true;
    return false;
  }

  public boolean isWithin(IntersectionMatrix im) {
    boolean b1 = (im
        .get(IntersectionMatrix.Inner, IntersectionMatrix.Outer) == IntersectionMatrix.EmptyDim);

    if (b1)
      return true;
    return false;
  }

  public List<Polygon> getRing(int a, int b) {
    List<Fragment> fragments = new ArrayList<Fragment>();

    fillFragmentList(fragments, fragments1, a);
    fillFragmentList(fragments, fragments2, b);
    fillFragmentList(fragments, fragments1, Fragment.Border);

    List<Polygon> result = new ArrayList<Polygon>();
    Ring r = join(fragments);
    while (r != null) {
      assert r.isValid() : "the ring is not simple";
      addRing(r, result);
      r = join(fragments);
    }

    clearFlag(fragments);
    return result;
  }

  private void addRing(Ring r, List<Polygon> pgs) {
    List<Polygon> newPgs = new ArrayList<Polygon>();
    List<Polygon> oldPgs = new ArrayList<Polygon>();
    for (int i = 0, n = pgs.size(); i < n; i++) {
      Polygon pg = pgs.get(i);
      if (r.containLineStringIn(pg.getShell())) {
        List<Ring> rr = new ArrayList<Ring>();
        rr.add(pg.getShell());
        newPgs.add(new Polygon(r, rr));
        oldPgs.add(pg);
      } else if (pg.getShell().containLineStringIn(r)) {
        List<Ring> rr = new ArrayList<Ring>();
        rr.add(r);
        newPgs.add(new Polygon(pg.getShell(), rr));
        oldPgs.add(pg);
      }
    }

    if (newPgs.size() == 0) {
      pgs.add(new Polygon(r));
    } else {
      for (Polygon pg : oldPgs) {
        pgs.remove(pg);
      }
      pgs.addAll(newPgs);
    }
  }

  private void fillFragmentList(List<Fragment> result, List<Fragment> old,
      int a) {
    for (Fragment fra : old) {
      if (fra.isContainIn() == a) {
        result.add(fra);
      }
    }
  }

  private Ring join(List<Fragment> fragment) {
    CoordSeqEditor line = new CoordSeqEditor();
    int n = fragment.size();
    boolean none = true;

    while (true) {
      for (int i = 0; i < n; i++) {
        if (!fragment.get(i).isFlag()) {
          LineString ls = fragment.get(i).getLineString();
          if (line.canJoin(ls.getPoints())) {
            line.join(ls.getPoints());
            fragment.get(i).setFlag(true);
            none = false;
          }
        }
      }
      if (none) {
        break;
      }
      none = true;
    }
    if (line.isEmpty()) {
      return null;
    }
    assert line.isClose() : "the ring is not close";

    line.deleteOverPoint();
    line.close();

    return new Ring(line.toCoordinateSeq());
  }

  private void clearFlag(List<Fragment> fragment) {
    for (Fragment fra : fragment) {
      fra.setFlag(false);
    }
  }

  @Override
  public String toString() {
    return "FragmentCollection [fragments1size=" + fragments1.size()
        + ", fragments2size=" + fragments2.size() + "]";
  }
}
TOP

Related Classes of chunmap.model.operate.overlay.FragmentCollection

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.