001/**
002 * AbstractPointGeomList -- Interface and implementation in common to all point geometry
003 * element lists.
004 *
005 * Copyright (C) 2009-2017, by Joseph A. Huwaldt. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or modify it under the terms
008 * of the GNU Lesser General Public License as published by the Free Software Foundation;
009 * either version 2 of the License, or (at your option) any later version.
010 *
011 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013 * PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License along with
016 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
017 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
018 */
019package geomss.geom;
020
021import static geomss.geom.AbstractGeomElement.RESOURCES;
022import static java.util.Objects.requireNonNull;
023
024/**
025 * Partial implementation of a named list of {@link PointGeometry} objects.
026 * <p>
027 * WARNING: This list allows geometry to be stored in different units. If consistent units
028 * are required, then the user must specifically convert the list items.
029 * </p>
030 *
031 * <p> Modified by: Joseph A. Huwaldt </p>
032 *
033 * @author Joseph A. Huwaldt, Date: May 3, 2009
034 * @version January 26, 2017
035 *
036 * @param <T> The sub-type of this AbstractPointGeomList list.
037 * @param <E> The type of PointGeometry element contained in this geometry list.
038 */
039@SuppressWarnings({"CloneableImplementsClone", "serial"})
040public abstract class AbstractPointGeomList<T extends AbstractPointGeomList, E extends PointGeometry>
041        extends AbstractGeomList<T, E> implements PointGeometry<T> {
042
043    /**
044     * Replaces the <@link PointGeometry> at the specified position in this list with the
045     * specified element. Null elements are ignored. The input element must have the same
046     * physical dimensions as the other items in this list, or an exception is thrown.
047     *
048     * @param index   The index of the element to replace. (0 returns the 1st element, -1
049     *                returns the last, -2 returns the 2nd from last, etc).
050     * @param element The element to be stored at the specified position. May not be null.
051     * @return The element previously at the specified position in this list.
052     * @throws java.lang.IndexOutOfBoundsException - if  <code>index > thisSize()</code>
053     * @throws DimensionException if the input element's dimensions are different from
054     * this list's dimensions.
055     */
056    @Override
057    public E set(int index, E element) {
058        requireNonNull(element);
059        if (size() > 0 && element.getPhyDimension() != this.getPhyDimension())
060            throw new DimensionException(RESOURCES.getString("dimensionErr"));
061        
062        return super.set(index, element);
063    }
064
065    /**
066     * Inserts the specified {@link PointGeometry} at the specified position in this list.
067     * Shifts the element currently at that position (if any) and any subsequent elements
068     * to the right (adds one to their indices). Null values are ignored. The input
069     * value must have the same physical dimensions as the other items in this list, or
070     * an exception is thrown.
071     * <p>
072     * Note: If this method is used concurrent access must be synchronized (the table is
073     * not thread-safe).
074     * </p>
075     *
076     * @param index the index at which the specified element is to be inserted. (0 returns
077     *              the 1st element, -1 returns the last, -2 returns the 2nd from last,
078     *              etc).
079     * @param value the element to be inserted. May not be null.
080     * @throws IndexOutOfBoundsException if <code>index > thisSize()</code>
081     * @throws DimensionException if the input element's dimensions are different from
082     * this list's dimensions.
083     */
084    @Override
085    public void add(int index, E value) {
086        requireNonNull(value);
087        if (size() > 0 && value.getPhyDimension() != this.getPhyDimension())
088            throw new DimensionException(RESOURCES.getString("dimensionErr"));
089        
090        super.add(index, value);
091    }
092
093    /**
094     * Returns the number of physical dimensions of the geometry element. This
095     * implementation always returns the physical dimension of the underlying
096     * {@link PointGeometry} objects or 0 if this list has no PointGeometry objects in it.
097     */
098    @Override
099    public int getPhyDimension() {
100        if (isEmpty())
101            return 0;
102        return get(0).getPhyDimension();
103    }
104
105    /**
106     * Return the total number of points in this geometry element.
107     */
108    @Override
109    public int getNumberOfPoints() {
110        int sum = 0;
111        for (int i = this.size() - 1; i >= 0; --i) {
112            PointGeometry e = this.get(i);
113            sum += e.getNumberOfPoints();
114        }
115        return sum;
116    }
117}