/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * * 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.geotools.geometry.iso.primitive; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.RandomAccessFile; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import junit.framework.TestCase; import org.geotools.geometry.GeometryBuilder; import org.geotools.geometry.iso.PositionFactoryImpl; import org.geotools.geometry.iso.coordinate.GeometryFactoryImpl; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.hsqldb.lib.StopWatch; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.PositionFactory; import org.opengis.geometry.coordinate.GeometryFactory; import org.opengis.geometry.coordinate.LineSegment; import org.opengis.geometry.coordinate.PointArray; import org.opengis.geometry.coordinate.LineString; import org.opengis.geometry.coordinate.Triangle; import org.opengis.geometry.primitive.Curve; import org.opengis.geometry.primitive.CurveSegment; import org.opengis.geometry.primitive.OrientableCurve; import org.opengis.geometry.primitive.PrimitiveFactory; import org.opengis.geometry.primitive.Curve; import org.opengis.geometry.primitive.Point; import org.opengis.geometry.primitive.Ring; import org.opengis.geometry.primitive.Surface; import org.opengis.geometry.primitive.SurfaceBoundary; import org.opengis.geometry.primitive.SurfacePatch; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * @author sanjay * * * @source $URL$ */ public class SurfaceTest extends TestCase { GeometryBuilder builder; protected void setUp() throws Exception { super.setUp(); builder = new GeometryBuilder(DefaultGeographicCRS.WGS84); } /** We need to create a large surface with 7000 points */ public void testLargeSurfaceFactory(){ DefaultGeographicCRS crs = DefaultGeographicCRS.WGS84; PositionFactory postitionFactory = new PositionFactoryImpl( crs ); PrimitiveFactory primitiveFactory = new PrimitiveFactoryImpl( crs, postitionFactory ); GeometryFactory geometryFactory = new GeometryFactoryImpl( crs, postitionFactory ); int NUMBER = 100000; double delta = 360.0 / (double) NUMBER; PointArray points = postitionFactory.createPointArray(); for( double angle = 0.0; angle < 360.0; angle += delta ){ double ordinates[] = new double[]{ Math.sin( Math.toRadians(angle) ), Math.cos( Math.toRadians(angle) ) }; DirectPosition point = postitionFactory.createDirectPosition( ordinates ); points.add( point ); } List<OrientableCurve> curves = new ArrayList<OrientableCurve>(); // A curve will be created // - The curve will be set as parent curves for the Curve segments // - Start and end params for the CurveSegments will be set List<CurveSegment> segmentList = new ArrayList<CurveSegment>(); for( int i=0; i<points.length();i++){ int start = i; int end = (i+1)%points.size(); DirectPosition point1 = points.getDirectPosition( start, null ); DirectPosition point2 = points.getDirectPosition( end, null ); LineSegment segment = geometryFactory.createLineSegment( point1, point2 ); segmentList.add( segment ); } Curve curve = primitiveFactory.createCurve( segmentList ); curves.add( curve); Ring ring = primitiveFactory.createRing( curves ); SurfaceBoundary boundary = primitiveFactory.createSurfaceBoundary(ring,new ArrayList()); Surface surface = primitiveFactory.createSurface(boundary); } /** We need to create a large surface with 7000 points */ public void testLargeSurfaceBuilder(){ int NUMBER = 100000; double delta = 360.0 / (double) NUMBER; PointArray points = builder.createPointArray(); for( double angle = 0.0; angle < 360.0; angle += delta ){ DirectPosition point = builder.createDirectPosition(); point.setOrdinate( 0, Math.sin( Math.toRadians(angle) ) ); point.setOrdinate( 1, Math.cos( Math.toRadians(angle) ) ); points.add( point ); } List<OrientableCurve> curves = new ArrayList<OrientableCurve>(); // A curve will be created // - The curve will be set as parent curves for the Curve segments // - Start and end params for the CurveSegments will be set List<LineSegment> segmentList = new ArrayList<LineSegment>(); for( int i=0; i<points.length();i++){ int start = i; int end = (i+1)%points.size(); DirectPosition point1 = points.getDirectPosition( start, null ); DirectPosition point2 = points.getDirectPosition( end, null ); LineSegment segment = builder.createLineSegment( point1, point2 ); segmentList.add( segment ); } Curve curve = builder.createCurve( segmentList ); curves.add( curve); Ring ring = builder.createRing( curves ); SurfaceBoundary boundary = builder.createSurfaceBoundary(ring ); Surface surface = builder.createSurface(boundary); } private List<Triangle> createTestTriangle1(GeometryBuilder builder) { GeometryFactoryImpl tCoordFactory = (GeometryFactoryImpl) builder.getGeometryFactory(); PrimitiveFactoryImpl tPrimFactory = (PrimitiveFactoryImpl) builder.getPrimitiveFactory(); ArrayList<double[][]> tDoubleList = new ArrayList<double[][]>(); tDoubleList.add(new double[][]{{0,0},{100,100},{0, 100}}); tDoubleList.add(new double[][]{{0,100},{100,100},{50,200}}); tDoubleList.add(new double[][]{{50,200},{100,100},{150,200}}); ArrayList<Triangle> triangleList = tCoordFactory.createTriangles(tDoubleList); for (int i=0; i < triangleList.size(); i++) { Triangle triangle1 = triangleList.get(i); //System.out.println(triangle1); } //System.out.println(triangle1.get.getEnvelope()); //System.out.println(triangle1.getBoundary()); return triangleList; } /** * Create a surface on basis of SurfacePatches (Triangles) * @param aGeomFactory */ public void testSurface1() { PrimitiveFactoryImpl tPrimFactory = (PrimitiveFactoryImpl) builder.getPrimitiveFactory(); List<? extends SurfacePatch> triangleList = createTestTriangle1(builder); List<SurfacePatch> surfacePatches1 = (List<SurfacePatch>)triangleList; Surface surface1 = tPrimFactory.createSurface(surfacePatches1); //System.out.print("\n******************* SURFACE GENERATED BY SURFACEPATCHES"); this.testSurfaces((SurfaceImpl) surface1); } public Surface _testSurface2(GeometryBuilder builder) { GeometryFactoryImpl tCoordFactory = (GeometryFactoryImpl) builder.getGeometryFactory(); PrimitiveFactoryImpl tPrimFactory = (PrimitiveFactoryImpl) builder.getPrimitiveFactory(); List<DirectPosition> directPositionList = new ArrayList<DirectPosition>(); directPositionList.add(tCoordFactory.createDirectPosition(new double[] {20, 10})); directPositionList.add(tCoordFactory.createDirectPosition(new double[] {40, 10})); directPositionList.add(tCoordFactory.createDirectPosition(new double[] {50, 40})); directPositionList.add(tCoordFactory.createDirectPosition(new double[] {30, 50})); directPositionList.add(tCoordFactory.createDirectPosition(new double[] {10, 30})); directPositionList.add(tCoordFactory.createDirectPosition(new double[] {20, 10})); Ring exteriorRing = (Ring) tPrimFactory.createRingByDirectPositions(directPositionList); List<Ring> interiors = new ArrayList<Ring>(); SurfaceBoundaryImpl surfaceBoundary1 = tPrimFactory.createSurfaceBoundary(exteriorRing, interiors ); Surface surface2 = tPrimFactory.createSurface(surfaceBoundary1); //System.out.print("\n******************* SURFACE GENERATED BY SURFACEBOUNDARY"); this.testSurfaces((SurfaceImpl) surface2); // ***** clone() SurfaceImpl surface3 = null; try { surface3 = (SurfaceImpl) surface2.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } assertTrue(surface2 != surface3); this.testSurfaces((SurfaceImpl) surface3); // ***** getRepresentativePoint() double[] dp = surface2.getRepresentativePoint().getCoordinates(); assertTrue(dp[0] == 20); assertTrue(dp[1] == 10); return surface2; } private void testSurfaces(SurfaceImpl surface) { try { //System.out.print("\nSurface: " + surface); } catch (NullPointerException e) { } // System.out.print("\ngetBoundary: " + surface.getBoundary()); assertNotNull( surface.getBoundary() ); // System.out.print("\ngetEnvelope: " + surface.getEnvelope()); assertNotNull( surface.getEnvelope() ); // System.out.print("\ngetCoordinateDimension: " + surface.getCoordinateDimension());\ assertNotNull( surface.getCoordinateDimension() ); // System.out.print("\ngetDimension: " + surface.getDimension(null)); assertTrue(surface.isCycle() == false); } // public void testSlowGeometry() throws FileNotFoundException { // String fname = System.getenv("ESP_HOME") + "\\resources\\users\\petritis\\zzzPoints.bin"; // CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84; // GeometryBuilder builder = new GeometryBuilder(crs); // GeometryFactoryImpl tGeomFactory = (GeometryFactoryImpl) builder.getGeometryFactory(); // PrimitiveFactoryImpl tPrimFactory = (PrimitiveFactoryImpl) builder.getPrimitiveFactory(); // // double[] imagePoints = null; // RandomAccessFile in = new RandomAccessFile(fname, "r"); // // ArrayList<Double> list = new ArrayList<Double>(); // double d; // while (true) { // try { // d = in.readDouble(); // } catch (IOException e) { // break; // } // list.add(d); // } // // imagePoints = new double[list.size()]; // int at = 0; // for (Double dv : list) { // imagePoints[at] = dv.doubleValue(); // at++; // } // // int numPoints = imagePoints.length / 2; // Point[] points = new Point[numPoints + 1]; // for (int i = 0; i < numPoints; i++) { // double[] coord = new double[2]; // coord[0] = imagePoints[i * 2]; // coord[1] = imagePoints[i * 2 + 1]; // points[i] = tPrimFactory.createPoint(coord); // } // points[numPoints] = points[0]; // // //StopWatch timer = new StopWatch(); // // LineString lineString = tGeomFactory.createLineString(new ArrayList(Arrays.asList(points))); // List curveSegmentList = Collections.singletonList(lineString); // List curveList = Collections.singletonList(tPrimFactory.createCurve(curveSegmentList)); // Ring exteriorRing = tPrimFactory.createRing(curveList); // SurfaceBoundary surfaceBoundary = tPrimFactory // .createSurfaceBoundary(exteriorRing, Collections.EMPTY_LIST); // Surface polygon = tPrimFactory.createSurface(surfaceBoundary); // //timer.stop(); // // System.out.println("numpoints=" + numPoints // + " time to create polygon: " ); // // assertNotNull(polygon); // } public void testFastSurfaceBuilder(){ double closed[] = new double[]{ 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0}; PointArray closedPoints = builder.createPointArray( closed ); SurfaceBoundary closedBoundary = builder.createSurfaceBoundary( closedPoints ); Surface closedSurface = builder.createSurface( closedBoundary ); // this example is not closed and would fail // if we were not calling createSurfaceBoundary double open[] = new double[]{ 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0,}; PointArray openPoints = builder.createPointArray( open ); SurfaceBoundary openBoundary = builder.createSurfaceBoundary( openPoints ); Surface openSurface = builder.createSurface( openBoundary ); assertEquals( "close array", openSurface, closedSurface ); } public void testFastSurfaceFactory() throws Exception { double closed[] = new double[]{ 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0}; Surface closedSurface = createSurfaceFast(closed); // this example is not closed and would fail // if we were not calling createSurfaceBoundary double open[] = new double[]{ 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0,}; PointArray openPoints = builder.createPointArray( open ); SurfaceBoundary openBoundary = builder.createSurfaceBoundary( openPoints ); Surface openSurface = builder.createSurface( openBoundary ); assertEquals( "close array", openSurface, closedSurface ); Surface surface = transmit(closedSurface); assertEquals( closedSurface, surface ); DirectPosition aPoint = surface.getRepresentativePoint(); DirectPosition point = transmit( aPoint ); assertEquals( aPoint, point ); } private <T> T transmit( T send ) throws IOException, ClassNotFoundException { // ensure we can serialize this beast // serialize ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject( send ); oos.close(); //deserialize byte[] pickled = out.toByteArray(); InputStream in = new ByteArrayInputStream(pickled); ObjectInputStream ois = new ObjectInputStream(in); return (T) ois.readObject(); } private Surface createSurfaceFast(double[] array ) { PositionFactory postitionFactory = builder.getPositionFactory(); PrimitiveFactory primitiveFactory = builder.getPrimitiveFactory(); GeometryFactory geometryFactory = builder.getGeometryFactory(); CoordinateReferenceSystem crs = builder.getCoordinateReferenceSystem(); int length = array.length / crs.getCoordinateSystem().getDimension(); PointArray closedPoints = postitionFactory.createPointArray( array, 0, length ); LineString lines = geometryFactory.createLineString(closedPoints); List<CurveSegment> segmentList = new ArrayList<CurveSegment>(); segmentList.add(lines); Curve curve = primitiveFactory.createCurve(segmentList); List<OrientableCurve> curves = new ArrayList<OrientableCurve>(); curves.add(curve); Ring ring = primitiveFactory.createRing(curves); SurfaceBoundary surfaceBoundary = primitiveFactory.createSurfaceBoundary( ring, Collections.EMPTY_LIST ); return primitiveFactory.createSurface(surfaceBoundary); } }