⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geoline.java

📁 geotools的源码
💻 JAVA
字号:
/*
 * @(#)GeoLine.java  0.5 22 May 1998  James Macgill
 *
 */

package uk.ac.leeds.ccg.geotools;

import java.lang.*;
import java.awt.*;

/** 
* This class is intended for storing georaphical line data such as
* roads, rivers etc.<p>
* <em>To Do:</em><br>
*
*
* @author Jamaes Macgill 
* @version 0.5 22 May 1998
* fast isNear code contributed by norbertf@users.sourceforge.net 
* slow isNear code by Ian 
*/
public class GeoLine extends GeoPolygon {
	public boolean acurate = false; // this means it will be faster 
	
	
	
	/**
	 * Number of points in line
	 */
	
	/**
	 * Array of points
	 */
	
	/**
	 * Minimum bounding box for line
	 */
	
	/**
	 * Create an empty polygon
	 */
	public GeoLine(){} //Empty
    
    
    
	/**
	 * Construct a line 
	 *
	 * @param id Line ID
	 * @param xpoints array of x values (npoints in size)
     * @param ypoints array of y values (npoints in size)
     * @param npoints number of points 
     */
	public GeoLine(int id,double[] xpoints,double[] ypoints,int npoints) {
		super(id,xpoints,ypoints,npoints);
	}

    /**
	 * Construct a line with no defined centroid or ID
	 *
	 * @param xpoints array of x values (npoints in size)
     * @param ypoints array of y values (npoints in size)
     * @param npoints number of points 
     */
	public GeoLine(double[] xpoints,double[] ypoints,int npoints) {
		this(-1,xpoints,ypoints,npoints);}

	
	
    /**
     * Construct a GeoPolygon based on an existing GeoPolygon
     *
     * @param poly GeoPolygon to clone
     */
	public GeoLine(GeoLine line) {
		this(line.id,line.xpoints,line.ypoints,line.npoints);}

	public GeoLine(int id, GeoPoint[] points){
		super(id,points);
	}
		public void setAcurate(boolean f){
			acurate = f;
		}

	  /**
	   * returns true if the specified point is inside the polygon
	   */
	   public boolean isNear(GeoPoint p,double w){
			GeoRectangle r = getBounds();
			GeoRectangle biggerRect = new GeoRectangle( r.getX() - w, r.getY() - w, r.getWidth() + w*2, r.getHeight() +w*2 );
	 
			 if(biggerRect.contains(p)){
				if(!acurate){
					 for(int i=0;i<npoints-1;i++){
						 double ax = xpoints[i]; double ay = ypoints[i];
						 double bx = xpoints[i+1]; double by = ypoints[i+1];
	 
						 double cx = p.getX(); double cy = p.getY();
						 // side-lengths of the triangle
						 double lc = Math.sqrt( (ax-bx)*(ax-bx) + (ay-by)*(ay-by) );
						 double la = Math.sqrt( (cx-bx)*(cx-bx) + (cy-by)*(cy-by) );
						 double lb = Math.sqrt( (cx-ax)*(cx-ax) + (cy-ay)*(cy-ay) );
						 // area of the triangle
						 double s= (la + lb + lc) /2;
						 double area = Math.sqrt(s * (s-la) * (s-lb) * (s-lc)) ;
						 // max area:
						 double maxarea = lc * w /2;
						 // max diagonal:
						 //double maxdiag = Math.sqrt( lc*lc + w*w);
						 double maxdiag = lc;
						 if (( area < maxarea ) && ( la < maxdiag ) && (lb < maxdiag )) 
								return true;
	 
					 }
				}else{ // acurate but slow
					for(int i=0;i<npoints-1;i++){
						GeoPoint p1=new GeoPoint(xpoints[i],ypoints[i]);
						GeoPoint p2=new GeoPoint(xpoints[i+1],ypoints[i+1]);
						if(p1.getY()>p2.getY()){
							GeoPoint tmp = p1;
							p1=p2;
							p2=tmp;
						}

						double dx=p2.getX()-p1.getX();
						double dy=p2.getY()-p1.getY();
						double alpha = Math.atan2(dy,dx);
						dy = (w)*Math.sin(Math.PI/2.0-alpha);
						dx = (w)*Math.cos(Math.PI/2.0-alpha);
						double [] x= new double[4];
						double [] y= new double[4];
						x[0]=p1.getX()-dx; y[0]=p1.getY()+dy;
						x[1]=p2.getX()-dx; y[1]=p2.getY()+dy;
						x[2]=p2.getX()+dx; y[2]=p2.getY()-dy;
						x[3]=p1.getX()+dx; y[3]=p1.getY()-dy;
						GeoPolygon gp = new GeoPolygon(0,0.0,0.0,x,y,4);
						GeoCircle gc = new GeoCircle(0,p1,(double)w);
						if(gc.contains(p)) return true;
						gc = new GeoCircle(0,p2,(double)w);
						if(gc.contains(p)) return true;
						if(gp.contains(p)) return true;
					}
				}// acurate	
			}


	    return false; 
	   }

	   public boolean isNear(double x,double y,double w){
	    GeoPoint p = new GeoPoint(x,y);
	    return isNear(p,w);
	   }


	/**
	* This method is EXPERIMENTAL & BUGGY. Don't rely on this to work at this point
	* The method checks for an intersection between this object's line and a given line
	* Please note that at this time, a line can only have two points! A geoline object
	* in general can have more than two points.
	* The algorithm used is taken from the comp.graphics.algorithms FAQ,
	* available at http://www.cs.ruu.nl/wais/html/na-dir/graphics/algorithms-faq.html
	* and posted regularly at that newsgroup. Subject 1.03 at this time of writing
	* the algorithm basically solves the two line equations. I've adjusted the algorithm slightly.
	* In the FAQ r is calculated as r = numerator/denumerator, and s = numerator/denumerator
	* As the denumerators are identical, and an intersection exists if both 0<=r<=1 and 0<=s<=1
	* I calculate r = numerator, s = numerator. Then I check for 0<=r<=denumerator and 0<=s<=denumerator
	* this prevents any potential divide by zero as well.
	*
	* We don't calculate the intersection point,
	* though that should be done easily by solving :
	* Intersection point P.x = Line1.pointA.x + r * (Line1.pointB.x-Line1.pointA.x)
	* Intersection point P.y = Line1.pointA.y + r * (Line1.pointB.y-Line1.pointA.y)
	* (also taken from that faq).
	* One last thing : I'm definitely no expert at this, so don't trust me for
	* implementing this correctly. (though I checked the code before releasing :) )
	* Creation date: (11/22/00 10:51:36 AM)
	* @return boolean true if lines intersect
	* @param l uk.ac.leeds.ccg.geotools.GeoLine
	* @author Mathieu van Loon
	* @version 0.1
	*/
	public boolean intersects(GeoLine l, boolean debug) throws IllegalArgumentException {
		System.err.println("Geoline.intersects is called. this code is buggy. Don't use it.");

		// Check to make sure each line has only two points
		if(this.npoints > 2) throw new IllegalArgumentException("This geoline object has more than 2 points. I can't handle that. sorry");
		if(l.npoints > 2) throw new IllegalArgumentException("The given geoline object has more than 2 points. I can't handle that. sorry");

		// calculate stuff
		double r = ((this.ypoints[0] - l.ypoints[0]) * (l.xpoints[1] - l.xpoints[0])) - ((this.xpoints[0] - l.xpoints[0]) * (l.ypoints[1] - l.ypoints[0]));
		double s = ((this.ypoints[0] - l.ypoints[0]) * (this.xpoints[1] - this.xpoints[0])) - ((this.xpoints[0] - l.xpoints[0]) * (this.ypoints[1] - this.ypoints[0]));
		double denumerator = ((this.xpoints[1] - this.xpoints[0]) * (l.ypoints[1] - l.ypoints[0])) - ((this.ypoints[1] - this.ypoints[0]) * (l.xpoints[1] - l.xpoints[0]));

		// determine whether an intersection exists
		if(denumerator==0) {
			if(r==0) {
				// The lines are collinear.
				if(debug)System.out.println("Collinear lines found");
				if(debug)System.out.println("r:"+r+"--s:"+s+"--d:"+denumerator);
				return true;
			} else {
				// The lines are parallel
				if(debug)System.out.println("parallel lines found");
				if(debug)System.out.println("r:"+r+"--s:"+s+"--d:"+denumerator);
				return false;
			}
		}
		if(denumerator>0) {
			if(0<=r && r<=denumerator && 0<=s && s<=denumerator) {
				// an intersection exists
				if(debug)System.out.println("Intersection found");
				if(debug)System.out.println("r:"+r+"--s:"+s+"--d:"+denumerator);
				return true;
			} else {
				// no intersection exists
				if(debug)System.out.println("No Intersection found"+s+"---"+r);
	//			if(debug)System.out.println("r:"+r+"--s:"+s+"--d:"+denumerator);
				return false;
			}
		} else {
			if(denumerator<=r && r<=0 && denumerator<=s && s<=0) {
				// an intersection exists
				if(debug)System.out.println("R->Intersection found");
				if(debug)System.out.println("R->r:"+r+"--s:"+s+"--d:"+denumerator);
				return true;
			} else {
				// no intersection exists
				r= r / denumerator;
				s= s /denumerator;
				if(debug)System.out.println("R->No Intersection found"+s+"---"+r);
				//if(debug)System.out.println("R->r:"+r+"--s:"+s+"--d:"+denumerator);
				return false;
			}
		}
	}

	public String toString(){
   StringBuffer sb = new StringBuffer();
   sb.append("GeoLine : [id ");
   sb.append(id);
   sb.append("] ");
   for(int i=0;i<npoints;i++){
      sb.append("{");
      sb.append(xpoints[i]);
      sb.append(",");
      sb.append(ypoints[i]);
      sb.append("} ");
   }
   return sb.toString();
	}
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -