/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.processing.coverage.isoline2; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import java.util.Collections; import java.util.LinkedList; /** * A construction is a 2 edge line string. * Each edge append coordinates at opposite ends. * * @author Johann Sorel (Geomatys) */ public final class Construction { private static final GeometryFactory GF = new GeometryFactory(); private LinkedList<Coordinate> lst = new LinkedList<Coordinate>(); private final Edge edge1; private final Edge edge2; private final double level; private boolean locked = false; public Construction(double level) { edge1 = new Edge(true); edge2 = new Edge(false); this.level = level; } public Edge getEdge1() { return edge1; } public Edge getEdge2() { return edge2; } public double getLevel() { return level; } public Geometry toGeometry(){ if(locked){ throw new IllegalStateException("Construction has been merged, should not be used anymore."); } if(lst.size()==1) return null; final Coordinate[] coords = lst.toArray(new Coordinate[lst.size()]); return GF.createLineString(coords); } public void merge(Edge otherEdge){ final Construction ocst = otherEdge.getConstruction(); if(this.equals(ocst)){ //closing a construction return; } if(this.lst.getFirst().equals2D(ocst.lst.getLast())){ //add at the beginning of this segment this.lst.removeFirst(); this.lst.addAll(0, ocst.lst); }else if(this.lst.getLast().equals2D(ocst.lst.getFirst())){ //add at the end of this segment this.lst.removeLast(); this.lst.addAll(ocst.lst); }else if(this.lst.getFirst().equals2D(ocst.lst.getFirst())){ //flip this list and add at the end of this segment //flip = true; Collections.reverse(lst); this.flipEdges(); this.lst.removeLast(); this.lst.addAll(ocst.lst); }else if(this.lst.getLast().equals2D(ocst.lst.getLast())){ //flip other list and add at the end of this segment //flip = true; Collections.reverse(lst); this.flipEdges(); this.lst.removeFirst(); this.lst.addAll(0,ocst.lst); }else{ throw new IllegalArgumentException("Strings can not be merged, no common point"); } ocst.locked = true; ocst.lst = this.lst; return; } private void flipEdges(){ edge1.atEnd = !edge1.atEnd; edge2.atEnd = !edge2.atEnd; } @Override public boolean equals(Object obj) { return ((Construction)obj).lst == this.lst; } @Override public int hashCode() { return 17; } public void update(Boundary bnd){ if(bnd==null) return; bnd.VTop = update(bnd.VTop); bnd.VMiddle = update(bnd.VMiddle); bnd.VBottom = update(bnd.VBottom); bnd.HLeft = update(bnd.HLeft); bnd.HMiddle = update(bnd.HMiddle); bnd.HRight = update(bnd.HRight); } private Edge update(Edge edge){ if(edge != null && edge.getConstruction().equals(this)){ if(edge.atEnd){ return (edge1.atEnd) ? edge1 : edge2; }else{ return (!edge1.atEnd) ? edge1 : edge2; } } return edge; } public final class Edge{ private boolean atEnd; public Edge(boolean atEnd) { this.atEnd = atEnd; } public Construction getConstruction(){ return Construction.this; } public void add(Coordinate coord){ if(locked) throw new IllegalStateException("Construction has been merged, should not be used anymore."); if(atEnd){ lst.addLast(new Coordinate(coord)); }else{ lst.addFirst(new Coordinate(coord)); } } public Coordinate getLast(){ if(atEnd){ return lst.getLast(); }else{ return lst.getFirst(); } } public boolean isPonctual(){ return Construction.this.lst.size() == 1; } @Override public boolean equals(Object obj) { return getConstruction().equals( ((Edge)obj).getConstruction() ); } @Override public int hashCode() { return 3; } } }