Re: [Jts-topo-suite-user] MBR Scaling to initial area
Brought to you by:
dr_jts
From: Stefan S. <ss...@ge...> - 2011-10-12 16:50:36
|
/*********************************************** * created on 22 oct. 2004 * last modified: 20.11.2005 [added LineString scaling] * * author: marius (IGN) and sstein (UniZH) * * description: * stretches a polygon or Multi polygon; * stretch does allow rotations * ***********************************************/ package ch.unizh.geo.algorithms; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateFilter; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; /** * @description: * stretches a polygon or Multi polygon; * stretch does allow rotations, * * @author marius * */ public class StretchGeometry { /** * Stretch the Polygon along a direction with a given scale from a point. * *@param geom the ¨Polygon to stretch. *@param x0 the X coordinate of the point from where to stretch. *@param y0 the Y coordinate of the point from where to stretch. *@param angle the angle of the direction to stretch. (angle from the growing X axis) *@param scale the stretching scale. */ public static void stretchPolygon(Polygon geom, double x0, double y0, double angle, double scale){ Point centroid = (Point)geom.getCentroid().clone(); //save copy for back transformation //--rotate the polygon rotate(geom, x0, y0, -1.0*angle); //--stretch the shell of the polygon along the X axis Coordinate[] coord=geom.getExteriorRing().getCoordinates(); for(int i=0;i<coord.length;i++){ coord[i].x=x0+scale*(coord[i].x-x0); } //--stretch the holes of the polygon along the X axis for(int j=0;j<geom.getNumInteriorRing();j++){ Coordinate[] holeCoord=geom.getInteriorRingN(j).getCoordinates(); for(int i=0;i<holeCoord.length;i++){ holeCoord[i].x=x0+scale*(holeCoord[i].x-x0); } } //--rotate back the polygon rotate(geom, x0, y0, angle); return; } /** * Stretch the LineString along a direction with a given scale from a point. * *@param geom the Line to stretch. *@param x0 the X coordinate of the point from where to stretch. *@param y0 the Y coordinate of the point from where to stretch. *@param angle the angle of the direction to stretch. (angle from the growing X axis) *@param scale the stretching scale. */ public static void stretchLine(LineString geom, double x0, double y0, double angle, double scale){ Point centroid = (Point)geom.getCentroid().clone(); //save copy for back transformation //rotate the LS rotateLS(geom, -1.0*angle); //rotatePoint(x0, y0, -1.0*angle, centroid.getX(), centroid.getY()); //stretch the shell of the polygon along the X axis Coordinate[] coord=geom.getCoordinates(); for(int i=0;i<coord.length;i++){ coord[i].x=x0+scale*(coord[i].x-x0); } //rotate back the LS rotateLS(geom, angle); //rotatePoint(x0, y0, angle, centroid.getX(), centroid.getY()); return; } /** * Stretch the MultiPolygon along a direction with a given scale from a point. * *@param geom the MultiPolygon to stretch. *@param x0 the X coordinate of the point from where to stretch. *@param y0 the Y coordinate of the point from where to stretch. *@param angle the angle of the direction to stretch. (angle from the growing X axis) *@param scale the stretching scale. */ public static void stretchMultiPolygon(MultiPolygon geom, double x0, double y0, double angle, double scale){ for(int i=0;i<geom.getNumGeometries();i++){ stretchPolygon((Polygon)geom.getGeometryN(i), x0, y0, angle, scale); } return; } /** * Stretch the Polygon along a direction with a given scale from the center point. * *@param geom the Polygon to stretch. *@param angle the angle of the direction to stretch. (angle from the growing X axis) *@param scale the stretching scale. */ public static void stretchPolygon(Polygon geom, double angle, double scale){ stretchPolygon(geom, geom.getCentroid().getX(), geom.getCentroid().getY(), angle, scale); } /** * Stretch the MultiPolygon along a direction with a given scale from the center point. * *@param geom the MultiPolygon to stretch. *@param angle the angle of the direction to stretch. (angle from the growing X axis) *@param scale the stretching scale. */ public static void stretchMultiPolygon(MultiPolygon geom, double angle, double scale){ stretchMultiPolygon(geom, geom.getCentroid().getX(), geom.getCentroid().getY(), angle, scale); } /** * * @param x * @param y * @param angle * @param x0 center of rot * @param y0 center of rot */ public static void rotatePoint(double x, double y, double x0, double y0, double angle){ double c=Math.cos(angle), s=Math.sin(angle); x=x0+c*(x-x0)-s*(y-y0); y=y0+s*(x-x0)+c*(y-y0); } public static void rotate(Polygon geom, double x0, double y0, double angle){ //calculate it only one time double c=Math.cos(angle), s=Math.sin(angle); //rotate the shell of the polygon Coordinate[] coord=geom.getExteriorRing().getCoordinates(); for(int i=0;i<coord.length;i++){ double x=coord[i].x, y=coord[i].y; coord[i].x=x0+c*(x-x0)-s*(y-y0); coord[i].y=y0+s*(x-x0)+c*(y-y0); } //rotate the holes of the polygon for(int j=0;j<geom.getNumInteriorRing();j++){ Coordinate[] coord2=geom.getInteriorRingN(j).getCoordinates(); for(int i=0;i<coord2.length;i++){ double x=coord2[i].x, y=coord2[i].y; coord2[i].x=x0+c*(x-x0)-s*(y-y0); coord2[i].y=y0+s*(x-x0)+c*(y-y0); } } return; } public static void rotate(MultiPolygon geom, double x0, double y0, double angle){ for(int i=0;i<geom.getNumGeometries();i++){ rotate((Polygon)geom.getGeometryN(i), x0, y0, angle); } return; } public static void rotate(Polygon geom, double angle){ rotate(geom, geom.getCentroid().getX(), geom.getCentroid().getY(), angle); } public static void rotate(MultiPolygon geom, double angle){ rotate(geom, geom.getCentroid().getX(), geom.getCentroid().getY(), angle); } public static void rotateLS(LineString line, double angle){ rotateLS(line.getCentroid().getX(),line.getCentroid().getY(), angle, line); } public static void rotateLS(double x0, double y0, double angle, LineString myLineString){ double x1, y1, xn ,yn; LineString newGeom = myLineString; Coordinate[] coordList = myLineString.getCoordinates(); int nrPoints = myLineString.getNumPoints(); //double x0 = ancorPoint.getX(); //double y0 = ancorPoint.getY(); for (int i = 0; i < nrPoints; i++) { x1 = coordList[i].x; y1 = coordList[i].y; xn = (x1 - x0)* Math.cos(angle) - Math.sin(angle)*(y1 - y0) + x0; yn = (x1 - x0)* Math.sin(angle) + Math.cos(angle)*(y1 - y0) + y0; coordList[i].x = xn; coordList[i].y = yn; } GeometryFactory myFac = new GeometryFactory(); newGeom = myFac.createLineString(coordList); } } |