001/*
002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003 * Copyright (C) 2006 - JScience (http://jscience.org/)
004 * All rights reserved.
005 * 
006 * Permission to use, copy, modify, and distribute this software is
007 * freely granted, provided that this notice is preserved.
008 */
009package org.jscience.geography.coordinates;
010
011import javolution.context.ObjectFactory;
012import javolution.xml.XMLFormat;
013import javolution.xml.stream.XMLStreamException;
014
015import org.jscience.geography.coordinates.crs.CompoundCRS;
016import org.jscience.geography.coordinates.crs.CoordinateReferenceSystem;
017
018/**
019 * This class represents a coordinates made up by combining 
020 * two coordinates objects together.
021 * 
022 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
023 * @version 3.0, February 13, 2006
024 */
025public final class CompoundCoordinates<C1 extends Coordinates<?>, C2 extends Coordinates<?>>
026        extends Coordinates<CompoundCRS<C1, C2>> {
027
028    /**
029     * Holds the first coordinates. 
030     */
031    private C1 _first;
032
033    /**
034     * Holds the next coordinates. 
035     */
036    private C2 _next;
037
038    /**
039     * Returns a compound coordinates made up of the specified coordinates.
040     * 
041     * @param first the first coordinates.
042     * @param next the next coordinates. 
043     */
044    @SuppressWarnings("unchecked")
045    public static <T1 extends Coordinates<?>, T2 extends Coordinates<?>> CompoundCoordinates<T1, T2> valueOf(
046            T1 first, T2 next) {
047        CompoundCoordinates coord = FACTORY.object();
048        coord._first = first;
049        coord._next = next;
050        return coord;
051    }
052
053    @SuppressWarnings("unchecked")
054    private static final ObjectFactory<CompoundCoordinates> FACTORY = new ObjectFactory<CompoundCoordinates>() {
055
056        @Override
057        protected CompoundCoordinates create() {
058            return new CompoundCoordinates();
059        }
060
061    };
062
063    private CompoundCoordinates() {
064    }
065
066    /**
067     * Returns the first coordinates.
068     * 
069     * @return the first coordinates. 
070     */
071    public C1 getFirst() {
072        return _first;
073    }
074
075    /**
076     * Returns the next coordinates.
077     * 
078     * @return the next coordinates. 
079     */
080    public C2 getNext() {
081        return _next;
082    }
083
084    @SuppressWarnings("unchecked")
085    @Override
086    public CompoundCRS<C1, C2> getCoordinateReferenceSystem() {
087        return new CompoundCRS<C1, C2>((CoordinateReferenceSystem<C1>) _first.getCoordinateReferenceSystem(),
088                (CoordinateReferenceSystem<C2>) _next.getCoordinateReferenceSystem());
089    }
090
091    // OpenGIS Interface.
092    public int getDimension() {
093        return _first.getDimension() + _next.getDimension();
094    }
095
096    // OpenGIS Interface.
097    public double getOrdinate(int dimension) throws IndexOutOfBoundsException {
098        final int firstDimension = _first.getDimension();
099        if (dimension < firstDimension) {
100            return _first.getOrdinate(dimension);
101        } else {
102            return _next.getOrdinate(dimension - firstDimension);
103        }
104    }
105
106    @Override
107    public CompoundCoordinates<?, ?> copy() {
108        return CompoundCoordinates.valueOf(_first, _next);
109    }
110
111    // Default serialization.
112    //
113
114    @SuppressWarnings("unchecked")
115    static final XMLFormat<CompoundCoordinates> XML = new XMLFormat<CompoundCoordinates>(
116            CompoundCoordinates.class) {
117
118        @Override
119        public CompoundCoordinates newInstance(Class<CompoundCoordinates> cls,
120                InputElement xml) throws XMLStreamException {
121            return FACTORY.object();
122        }
123
124        @SuppressWarnings("unchecked")
125        @Override
126        public void read(InputElement xml, CompoundCoordinates coord)
127                throws XMLStreamException {
128            coord._first = xml.getNext();
129            coord._next = xml.getNext();
130        }
131
132        @Override
133        public void write(CompoundCoordinates coord, OutputElement xml)
134                throws XMLStreamException {
135            xml.add(coord._first);
136            xml.add(coord._next);
137        }
138    };
139
140    private static final long serialVersionUID = 1L;
141
142}