📄 geopolygon.java
字号:
/*
* @(#)GeoPolygon.java 0.5 17 April 1997 James Macgill
*
*/
package uk.ac.leeds.ccg.geotools;
import java.lang.*;
import java.awt.*;
import java.util.*;
/**
* This class is intended for storing georaphical polygons such as boundry data
* for wards, costlines etc.<p>
*
* @author Jamaes Macgill
* @version 0.5 17 April 1997
*/
public class GeoPolygon extends GeoShape {
/**
* control debugging. For now, either turn it off or on
*/
private final static boolean DEBUG=false;
/**
* Performance switch, to turn of use of Vector. use with CARE
*/
private boolean useVector = true;
/**
* Polygon centroid coordinates
*/
private double xcent,ycent;
/**
* Number of points in polygon
*/
public int npoints;
/**
* Area of polygon
*/
private double area;
/**
* Array of points
*/
public double xpoints[],ypoints[];
private Vector storedPoints = null;
private boolean pointsStored = false;
private boolean areaDone,centroidDone;
public static final int OUTSIDE = -1;
public static final int NA = Integer.MAX_VALUE;
/**
* Create an empty polygon
*/
public GeoPolygon(){
if ( useVector ) storedPoints = new Vector();
setBounds(new GeoRectangle());
} //Almost Empty
/**
* Construct a polygon with full details
*
* @param id polygon ID
* @param xcent x coordinate of centroid
* @param ycent y coordinate of centroid
* @param xpoints vector of x values in Doubles (npoints in size)
* @param ypoints vector of y values in Doubles (npoints in size)
* @param npoints number of points
*/
public GeoPolygon(int id,double xcent,double ycent,Vector xpoints,Vector ypoints) {
if ( useVector ) storedPoints = new Vector();
this.id = id;
this.npoints = xpoints.size();
//System.out.println("Building with "+npoints);
this.xpoints = new double[npoints];
this.ypoints = new double[npoints];
for(int i=0;i<npoints;i++){
this.xpoints[i] = ((Double)xpoints.elementAt(i)).doubleValue();
this.ypoints[i] = ((Double)ypoints.elementAt(i)).doubleValue();
}
//Update the bounding box
setBounds(new GeoRectangle());
for(int i = 0;i < npoints;i++) {
extendBounds(this.xpoints[i],this.ypoints[i]);
if(useVector) storedPoints.addElement(new GeoPoint(this.xpoints[i],this.ypoints[i]));
}
//calculateArea();
if(xcent == NA || ycent == NA){
//calculateCentroidLocation();
}
else{
this.xcent = xcent;
this.ycent = ycent;
centroidDone=true;
}
}
/**
* Construct a polygon with full details
*
* @param id polygon ID
* @param xcent x coordinate of centroid
* @param ycent y coordinate of centroid
* @param xpoints array of x values (npoints in size)
* @param ypoints array of y values (npoints in size)
* @param npoints number of points
*/
public GeoPolygon(int id,double xcent,double ycent,double[] xpoints,double[] ypoints,int npoints) {
if ( useVector ) storedPoints = new Vector();
this.id = id;
this.xpoints = new double[npoints];
this.ypoints = new double[npoints];
this.npoints = npoints;
//Add a try here to catch failed array copy
System.arraycopy(xpoints,0,this.xpoints,0,npoints);
System.arraycopy(ypoints,0,this.ypoints,0,npoints);
//Update the bounding box
setBounds(new GeoRectangle());
for(int i = 0;i < npoints;i++) {
extendBounds(xpoints[i],ypoints[i]);
if(useVector)storedPoints.addElement(new GeoPoint(xpoints[i],ypoints[i]));
}
calculateArea();
if(xcent == NA || ycent == NA){
calculateCentroidLocation();
}
else{
this.xcent = xcent;
this.ycent = ycent;
}
// statsDone=true;
}
/**
* Construct a polygon with no defined centroid
*
* @param id Polygon 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 GeoPolygon(int id,double[] xpoints,double[] ypoints,int npoints) {
this(id,NA,NA,xpoints,ypoints,npoints);
}
/**
* Construct a polygon and generate its centroid
* 08/May/2000 added call to calculateCentroidLocation
* @author James Macgill JM
* @param id Polygon ID
* @param points[] an Array of points to build the polygon off
*/
public GeoPolygon(int id,GeoPoint[] points) {
if ( useVector ) storedPoints = new Vector();
this.id = id;
//this.xcent = 0;
//this.ycent = 0;
this.xpoints = new double[points.length];
this.ypoints = new double[points.length];
this.npoints = points.length;
setBounds(new GeoRectangle());
for(int i = 0;i < npoints;i++) {
xpoints[i] = points[i].x;
ypoints[i] = points[i].y;
extendBounds(xpoints[i],ypoints[i]);
if(useVector)storedPoints.addElement(new GeoPoint(xpoints[i],ypoints[i]));
}
calculateArea();
calculateCentroidLocation();
}
/**
* Construct a polygon 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 GeoPolygon(double[] xpoints,double[] ypoints,int npoints) {
this(-1,NA,NA,xpoints,ypoints,npoints);}
/**
* Construct an empty polygon with ID and centroid only
*
* @param id polygon ID
* @param xcent x coordinate of centroid
* @param ycent y coordinate of centroid
*/
public GeoPolygon(int id,double xcent,double ycent) {
if ( useVector ) storedPoints = new Vector();
this.id = id;
this.xcent = xcent;
this.ycent = xcent;
setBounds(new GeoRectangle());
}
/**
* Construct a GeoPolygon based on an existing GeoPolygon
*
* @param poly GeoPolygon to clone
*/
public GeoPolygon(GeoPolygon poly) {
this(poly.id,poly.xcent,poly.ycent,poly.xpoints,poly.ypoints,poly.npoints);}
/**
* Add a vertex to the polygon
*
* @param x x coordinate of point to add
* @param y y coordinate of point to add
*/
public void addPoint(double x,double y) {
if(npoints > 0) {
double xtemp[];
double ytemp[];
xtemp = xpoints;
ytemp = ypoints;
xpoints = new double[npoints+1];
System.arraycopy(xtemp,0,xpoints,0,npoints);
xtemp=null;
ypoints = new double[npoints+1];
System.arraycopy(ytemp,0,ypoints,0,npoints);
ytemp=null;
}
else {
xpoints = new double[1];
ypoints = new double[1];
}
npoints++;
xpoints[npoints-1] = x;//-1 to account for 0 array indexing
ypoints[npoints-1] = y;
if(useVector)storedPoints.addElement(new GeoPoint(x,y));//is this risky?
extendBounds(x,y);
//calculateArea();//TODO JM:v.wastefull, save until a area request is made?
//calculateCentroidLocation();//TODO JM:v.wastefull, save until a area request is made?
areaDone=centroidDone=false;
}
/**
* Add a vertex to the polygon
*
* @param p A GeoPoint to add
*/
public void addPoint(GeoPoint p){
addPoint(p.x,p.y);
}
/**
* Returns a standard AWT.Polygon from the GeoPolygon
* <em>note</em> The GeoPolygon used doubles , the Polygon uses ints
* so there will be precision loss.
*/
public Polygon toAWTPolygon() {
int x[] = new int[npoints];
int y[] = new int[npoints];
// This next bit might throw a number exception put in try{} ?
for(int i=0;i<npoints;i++) {
x[i] = (int)xpoints[i];//Convert float to integer
y[i] = (int)ypoints[i];
}
return new Polygon(x,y,npoints);
}
/**
* Return the polygon ID
*/
public int getID(){
return id;
}
public void setID(int id){
this.id=id;
}
/**
* Return the area of this polygon.
* This value is calculated from the polygon data on construction
* and upon any changes to the polygon's points.
* @since 0.7.7.1 8/May/2000
* @author James Macgill
* @return double The area of this polygon
*/
public double getArea(){
if(!areaDone){
calculateArea();
}
return area;
}
/**
* Calculates and returns the perimeter of this polygon.<br>
* Value is currently generated per-request.
* @author James Macgill JM
* @since 0.7.7.1 8/May/2000
* @return double the perimeter of this polygon
*/
public double getPerimeter(){
double dist = 0;
int i;
for(i=0;i<npoints-1;i++){
dist+=Math.sqrt(((xpoints[i]-xpoints[i+1])*(xpoints[i]-xpoints[i+1]))+((ypoints[i]-ypoints[i+1])*(ypoints[i]-ypoints[i+1])));
}
return dist;
}
/**
* Return the centroid of this polygon.
* this value was either supplied to the constructor or has been
* calculated automaticaly.<br>
* automaticaly calculated centroids are not guaranteed to be inside the
* polygon, insted they represent the polygons center of mass.
* @since 0.7.7.1 8/May/2000
* @author James Macgill JM
* @return GeoPoint The centroid of this polygon
*/
public GeoPoint getCentroidLocation(){
if(!centroidDone){
calculateCentroidLocation();
}
return new GeoPoint(xcent,ycent);
}
/**
* Return the number of points that make the polygon
*/
public int getNPoints(){
return npoints;
}
/**
* get the geopoints as as an array of x or y
* @author Mathieu van Loon <mathieu@PLAYcollective.com>
*/
public double[] getPointsAsArrayX() {
return xpoints;
}
public double[] getPointsAsArrayY() {
return ypoints;
}
/**
* Drop the use of a Vector to store the points. This method
* is available for performance reasons. You will only want to use
* this method if you store a lot of GeoPolygons, and you wish
* to decrease the memory load.
* @author Mathieu van Loon <mathieu@PLAYcollective.com>
*/
public void dropVector() {
useVector = false;
storedPoints = null;
}
public final Vector getPoints(){
if(useVector)
{
return storedPoints;
} else
{
Vector reply = new Vector(npoints);
for(int i=0;i<npoints;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -