/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2007 - 2008, Open Source Geospatial Foundation (OSGeo) * (C) 2008 - 2009, Johann Sorel * * 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.geotoolkit.display; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Polygon; import java.util.logging.Level; import java.util.logging.Logger; import javax.measure.UnitConverter; import javax.measure.quantity.Length; import javax.measure.Unit; import org.apache.sis.measure.Units; import org.apache.sis.geometry.GeneralDirectPosition; import org.apache.sis.referencing.CRS; import org.geotoolkit.referencing.GeodeticCalculator; import org.geotoolkit.factory.AuthorityFactoryFinder; import org.geotoolkit.geometry.jts.JTS; import org.apache.sis.internal.referencing.ReferencingUtilities; import org.apache.sis.util.logging.Logging; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.parameter.ParameterValueGroup; import org.opengis.util.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.datum.Ellipsoid; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; /** * * @author Johann Sorel (Geomatys) * @module */ public class MeasureUtilities { private static final Logger LOGGER = Logging.getLogger("org.geotoolkit.display"); public static double calculateLenght(final Geometry geom, final CoordinateReferenceSystem geomCRS, final Unit<Length> unit){ if(geom == null || !(geom instanceof LineString)) return 0; final LineString line = (LineString) geom; Coordinate[] coords = line.getCoordinates(); try { final GeodeticCalculator calculator = new GeodeticCalculator(geomCRS); final GeneralDirectPosition pos = new GeneralDirectPosition(geomCRS); double lenght = 0; for(int i=0,n=coords.length-1;i<n;i++){ Coordinate coord1 = coords[i]; Coordinate coord2 = coords[i+1]; pos.ordinates[0] = coord1.x; pos.ordinates[1] = coord1.y; calculator.setStartingPosition(pos); pos.ordinates[0] = coord2.x; pos.ordinates[1] = coord2.y; calculator.setDestinationPosition(pos); lenght += calculator.getOrthodromicDistance(); } if(!Units.METRE.equals(unit)){ UnitConverter converter = Units.METRE.getConverterTo(unit); lenght = converter.convert(lenght); } return lenght; } catch (MismatchedDimensionException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (TransformException ex) { LOGGER.log(Level.WARNING, null, ex); } return 0; } public static double calculateArea(final Geometry geom, final CoordinateReferenceSystem geomCRS, final Unit unit){ if(geom == null || !(geom instanceof Polygon)) return 0; try { Envelope env = JTS.toEnvelope(geom); final GeographicCRS geoCRS = ReferencingUtilities.toNormalizedGeographicCRS(geomCRS); final MathTransform step0 = CRS.findOperation(geomCRS, geoCRS, null).getMathTransform(); Envelope genv = JTS.transform(env, step0); double centerMeridian = genv.getWidth()/2 + genv.getMinX(); double northParallal = genv.getMaxY() - genv.getHeight()/3 ; double southParallal = genv.getMinY() + genv.getHeight()/3 ; final Ellipsoid ellipsoid = geoCRS.getDatum().getEllipsoid(); MathTransformFactory f = AuthorityFactoryFinder.getMathTransformFactory(null); ParameterValueGroup p; p = f.getDefaultParameters("Albers_Conic_Equal_Area"); p.parameter("semi_major").setValue(ellipsoid.getSemiMajorAxis()); p.parameter("semi_minor").setValue(ellipsoid.getSemiMinorAxis()); p.parameter("central_meridian").setValue(centerMeridian); p.parameter("standard_parallel_1").setValue(northParallal); p.parameter("standard_parallel_2").setValue(southParallal); MathTransform step1 = CRS.findOperation(geomCRS, geoCRS, null).getMathTransform(); MathTransform step2 = f.createParameterizedTransform(p); MathTransform trs = f.createConcatenatedTransform(step1, step2); Geometry calculatedGeom = JTS.transform(geom, trs); double area = calculatedGeom.getArea(); if(unit != Units.SQUARE_METRE){ UnitConverter converter = Units.SQUARE_METRE.getConverterTo(unit); area = converter.convert(area); } return area; } catch (FactoryException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (MismatchedDimensionException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (TransformException ex) { LOGGER.log(Level.WARNING, null, ex); } return 0; } }