/**
* 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.List;
import chunmap.model.algorithm.LineAlgorithm;
import chunmap.model.algorithm.LinearReference;
import chunmap.model.coord.CoordinateArray;
import chunmap.model.coord.CoordinateSeq;
import chunmap.model.coord.CPoint;
import chunmap.model.coord.Transform;
import chunmap.model.elem.Envelope;
import chunmap.model.elem.EnvelopeBuf;
import chunmap.model.elem.LineSegment;
import chunmap.model.elem.PointLineBag;
/**
* 线串
*
* @author chunquedong
*
*/
public class LineString extends AbstractGeometry {
protected CoordinateSeq points;
public LineString(List<CPoint> pointList) {
this(pointList.toArray(new CPoint[0]));
}
public LineString(CPoint[] pointList) {
points = new CoordinateArray(pointList);
}
public LineString(CoordinateSeq points) {
this.points=points;
}
//------------------------------------------------------------------------getter
public CPoint getPoint(int index) {
return points.getCoordinate(index);
}
public int size() {
return points.size();
}
public CoordinateSeq getPoints()
{
return points;
}
public boolean isClosed()
{
return firstPoint().equals(lastPoint());
}
public CPoint firstPoint() {
return getPoint(0);
}
public CPoint lastPoint() {
return getPoint(size() - 1);
}
public Ring toLinearRing() {
return new Ring(points);
}
//------------------------------------------------------------------------geometry
@Override
protected Envelope calculateEnvelop() {
EnvelopeBuf env =new EnvelopeBuf();
for (CPoint p : points) {
env.extendEnvelop(p);
}
return env.toEnvelop();
}
@Override
public GeometryType getGeometryType() {
return GeometryType.LineString;
}
@Override
public String toString() {
return "LINESTRING" + toMyString();
}
public String toMyString() {
StringBuilder str = new StringBuilder();
str.append("(");
for (CPoint p : points) {
str.append(p.getX() + " " + p.getY() + ",");
}
str.deleteCharAt(str.lastIndexOf(","));
str.append(")");
return str.toString();
}
@Override
public Geometry getBoundary() {
List<GeoPoint> bs = new ArrayList<GeoPoint>();
bs.add(new GeoPoint(firstPoint()));
bs.add(new GeoPoint(lastPoint()));
return new MultiPoint(bs);
}
@Override
public GeometryCollection toGeometryCollection() {
List<LineString> gs = new ArrayList<LineString>();
gs.add(this);
return new MultiLineString(gs);
}
@Override
protected boolean isSimple() {
return LineAlgorithm.isSimple(this.getPoints());
}
/**
* 坐标变换
*/
@Override
public Geometry transform(Transform transf) {
List<CPoint> pointList = new ArrayList<CPoint>();
for (CPoint p : points) {
pointList.add(transf.convert(p));
}
return new LineString(pointList);
}
//------------------------------------------------------------------------system
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((points == null) ? 0 : points.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;
LineString other = (LineString) obj;
if (points == null) {
if (other.points != null)
return false;
} else if (!points.equals(other.points))
return false;
return true;
}
//------------------------------------------------------------------------util
public LineSegment getLineSegment(int i)
{
return new LineSegment(getPoint(i), getPoint(i+1));
}
public boolean onLineString(CPoint p)
{
if (!this.getEnvelop().contain(p))
{
return false;
}
return LineAlgorithm.onLineString(points, p);
}
public PointLineBag intersection(LineString l2)
{
if (!this.getEnvelop().hasIntersect(l2.getEnvelop()))
{
return new PointLineBag();
}
return LineAlgorithm.intersection(this.points, l2.points);
}
public boolean hasIntersection(LineString l2)
{
if (!this.getEnvelop().hasIntersect(l2.getEnvelop()))
{
return false;
}
return LineAlgorithm.hasIntersection(this.points, l2.points);
}
public boolean containLineString(LineString l2)
{
if (!this.getEnvelop().hasIntersect(l2.getEnvelop()))
{
return false;
}
return LineAlgorithm.containLineString(this.points, l2.points);
}
public double getLength()
{
return LinearReference.getLength(points);
}
}