/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-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; import java.awt.RenderingHints; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.geotools.factory.Factory; import org.geotools.factory.Hints; import org.geotools.geometry.iso.coordinate.DirectPositionImpl; import org.geotools.geometry.iso.coordinate.DoublePointArray; import org.geotools.geometry.iso.coordinate.PointArrayImpl; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.geometry.PositionFactory; import org.opengis.geometry.Precision; import org.opengis.geometry.PrecisionType; import org.opengis.geometry.coordinate.PointArray; import org.opengis.geometry.coordinate.Position; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * Default implementation of PositionFactory that stores contents using double. * <p> * You should be aware of the following: * <ul> * <li>createPositionList() is backed by an ArrayList * <li>createPositionList( double, int, int) is a custom efficient * implementation that does not support add * <li>createPositionList( float, int, int ) will copy the array contents into * individual DirectPositions. * </ul> * * @author Jody Garnett * * * * @source $URL$ */ public class PositionFactoryImpl implements Serializable, Factory, PositionFactory { private static final long serialVersionUID = 1L; final private Precision precision; final CoordinateReferenceSystem crs; private Map<RenderingHints.Key, Object> hintsWeCareAbout = new HashMap<RenderingHints.Key, Object>(); /** * This is just here so FactorySPI can find us. * We have set it up with a default (undocumented) configuration * for testing! */ public PositionFactoryImpl() { this( (Hints)null ); } /** * This is the constructor used by GeometryFactoryFinder when a user * requests a new instance. * The provided hints *must* be provided: * <ul> * <li>Hints.CRS * <li>Hints.PRECISION * </ul> * There is no default for these values - you must describe your data source * for us if we are to make useful Geometry object for you. * * @param hints Hints (must include CRS and PRECISION) */ public PositionFactoryImpl(Hints hints) { if (hints == null) { this.crs = DefaultGeographicCRS.WGS84; this.precision = new PrecisionModel(); } else { this.crs = (CoordinateReferenceSystem) hints.get(Hints.CRS); this.precision = new PrecisionModel(); } hintsWeCareAbout.put( Hints.CRS, crs ); hintsWeCareAbout.put( Hints.PRECISION, precision ); } public PositionFactoryImpl(CoordinateReferenceSystem crs) { this(crs, new PrecisionModel(PrecisionType.DOUBLE)); } public PositionFactoryImpl(CoordinateReferenceSystem crs, Precision precision) { assert( precision.getType() == PrecisionType.DOUBLE ); this.crs = crs; this.precision = precision; hintsWeCareAbout.put( Hints.CRS, crs ); hintsWeCareAbout.put( Hints.PRECISION, precision ); } /** * Report back to FactoryRegistry about our configuration. * <p> * FactoryRegistry will check to make sure that there are no duplicates * created (so there will be only a "single" PositionFactory created * with this configuration). * </p> */ public Map getImplementationHints() { return Collections.unmodifiableMap( hintsWeCareAbout ); } public DirectPosition createDirectPosition(double[] coords) throws MismatchedDimensionException { if (coords != null) return new DirectPositionImpl(crs, coords); return new DirectPositionImpl(crs); } public Position createPosition(Position position) { DirectPosition directPosition = position.getDirectPosition(); return new DirectPositionImpl(directPosition); } public PointArrayImpl createPointArray() { return new PointArrayImpl(crs); } public DoublePointArray createPointArray(final double[] array, final int start, final int end) { return new DoublePointArray(crs, array, start, end); } public PointArray createPointArray(float[] array, int start, int end) { PointArray pointArray = (PointArray) createPointArray(); int D = crs.getCoordinateSystem().getDimension(); if (D == 2) { for (int i = start; i < end; i += D) { double[] ordinates = new double[] { array[i], array[i + 1] }; pointArray.add(new DirectPositionImpl(crs, ordinates)); } } else if (D == 3) { for (int i = start; i < end; i += D) { double[] ordinates = new double[] { array[i], array[i + 1], array[i + 2] }; pointArray.add(new DirectPositionImpl(crs, ordinates)); } } else { for (int i = start; i < end; i += D) { double[] ordinates = new double[D]; for (int o = 0; i < D; i++) { ordinates[o] = array[i + o]; } pointArray.add(new DirectPositionImpl(crs, ordinates)); } } return pointArray; } public CoordinateReferenceSystem getCoordinateReferenceSystem() { return crs; } public Precision getPrecision() { return precision; } }