org.geolatte.geom.Positions Maven / Gradle / Ivy
Show all versions of geolatte-geom Show documentation
/*
* This file is part of the GeoLatte project.
*
* GeoLatte 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, either version 3 of the License, or
* (at your option) any later version.
*
* GeoLatte 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GeoLatte. If not, see .
*
* Copyright (C) 2010 - 2014 and Ownership of code is shared by:
* Qmino bvba - Romeinsestraat 18 - 3001 Heverlee (http://www.qmino.com)
* Geovise bvba - Generaal Eisenhowerlei 9 - 2140 Antwerpen (http://www.geovise.com)
*/
package org.geolatte.geom;
import org.geolatte.geom.crs.CoordinateReferenceSystem;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Factories for creating Positions.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 4/3/14
*/
public class Positions {
public static Map, PositionFactory>> registeredFactoriesMap;
static {
registeredFactoriesMap = new HashMap<>();
registeredFactoriesMap.put(G2D.class, new CanMakeG2D());
registeredFactoriesMap.put(G2DM.class, new CanMakeG2DM());
registeredFactoriesMap.put(G3D.class, new CanMakeG3D());
registeredFactoriesMap.put(G3DM.class, new CanMakeG3DM());
registeredFactoriesMap.put(C2D.class, new CanMakeP2D());
registeredFactoriesMap.put(C2DM.class, new CanMakeP2DM());
registeredFactoriesMap.put(C3D.class, new CanMakeP3D());
registeredFactoriesMap.put(C3DM.class, new CanMakeP3DM());
}
/**
* Factory method for {@code Position}s in the reference system.
*
* The coordinates array should be in normalized order. See
* {@link Position}
*
* @param coordinates the coordinates of the position
*
* @return the {@code Position} with the specified coordinates.
*/
@SuppressWarnings("unchecked")
public static P mkPosition(Class
pClass, double... coordinates) {
PositionFactory
factory = getFactoryFor( pClass );
return factory.mkPosition( coordinates );
}
@SuppressWarnings("unchecked")
public static
P mkPosition(CoordinateReferenceSystem
crs, double... coordinates) {
return mkPosition( crs.getPositionClass(), coordinates );
}
public static
PositionSequence
collect(Class
positionType, P... positions) {
PositionSequenceBuilder
builder = PositionSequenceBuilders.fixedSized(positions.length, positionType);
for(P p : positions) {
builder.add(p);
}
return builder.toPositionSequence();
}
@SuppressWarnings("unchecked")
public static
PositionFactory
getFactoryFor(Class
pClass) {
PositionFactory
pf = (PositionFactory
)registeredFactoriesMap.get(pClass);
if(pf != null) {
return pf;
}
throw new UnsupportedOperationException(
String.format(
"Position type %s unsupported",
pClass.getSimpleName()
)
);
}
/**
* Copies the source positions to a new PositionSequence.
*
*
The coordinates are taken as-is. If the target coordinate reference systems has a larger coordinate
* dimensions then the source, the specified defaultValue is used for the missing coordinate values.
*
* @param source
* @param targetPosClass target type of {@code Position}
* @param defaultValue default coordinate value
* @param
*
* @return a copy of the source positions
*/
public static PositionSequence copy(
final PositionSequence source,
final Class targetPosClass,
double defaultValue) {
PositionFactory
factory = Positions.getFactoryFor( targetPosClass );
final PositionSequenceBuilder
builder = PositionSequenceBuilders.fixedSized( source.size(), targetPosClass );
if ( source.isEmpty() ) {
return builder.toPositionSequence();
}
final double[] coords = new double[Math.max(
source.getCoordinateDimension(),
factory.getCoordinateDimension()
)];
Arrays.fill( coords, defaultValue );
PositionVisitor visitor = new PositionVisitor() {
public void visit(Q position) {
position.toArray( coords );
builder.add( coords );
}
};
source.accept( visitor );
return builder.toPositionSequence();
}
/**
* Copies the source positions to a new PositionSequence.
*
* The coordinates are taken as-is. If the target coordinate reference systems has a larger coordinate
* dimensions then the source, Double.NaN is used for the missing coordinate values.
*
* @param source
* @param targetPosClass target type of {@code Position}
* @param
*
* @return a copy of the source positions
*/
public static PositionSequence copy(
final PositionSequence source,
final Class targetPosClass) {
return copy(source, targetPosClass, Double.NaN);
}
//Factories
public static class CanMakeP2D implements PositionFactory {
@Override
public Class forClass() {
return C2D.class;
}
@Override
public int getCoordinateDimension() {
return 2;
}
@Override
public C2D mkPosition(double... coordinates) {
return (coordinates.length == 0 ? new C2D() : new C2D( coordinates[0], coordinates[1] ));
}
@Override
public boolean hasZComponent() {
return false;
}
@Override
public boolean hasMComponent() {
return false;
}
@Override
public int getMComponentIndex() {
return -1;
}
}
public static class CanMakeP2DM implements PositionFactory {
@Override
public Class forClass() {
return C2DM.class;
}
@Override
public int getCoordinateDimension() {
return 3;
}
@Override
public C2DM mkPosition(double... coordinates) {
return coordinates.length == 0 ? new C2DM() : new C2DM( coordinates[0], coordinates[1], coordinates[2] );
}
@Override
public boolean hasZComponent() {
return false;
}
@Override
public boolean hasMComponent() {
return true;
}
@Override
public int getMComponentIndex() {
return 2;
}
}
public static class CanMakeP3D implements PositionFactory {
@Override
public Class forClass() {
return C3D.class;
}
@Override
public int getCoordinateDimension() {
return 3;
}
@Override
public C3D mkPosition(double... coordinates) {
/*
In some cases we do not have 3 coordinates here but
* only two. in this case we are using 0.0 as z coordinate.
*/
return coordinates.length == 0 ? new C3D() : new C3D(
coordinates[0], coordinates[1],
coordinates.length > 2 ? coordinates[2] : 0.0
);
}
@Override
public boolean hasZComponent() {
return true;
}
@Override
public boolean hasMComponent() {
return false;
}
@Override
public int getMComponentIndex() {
return -1;
}
}
public static class CanMakeP3DM implements PositionFactory {
@Override
public Class forClass() {
return C3DM.class;
}
@Override
public int getCoordinateDimension() {
return 4;
}
@Override
public C3DM mkPosition(double... coordinates) {
return coordinates.length == 0 ? new C3DM() : new C3DM(
coordinates[0], coordinates[1], coordinates[2],
coordinates[3]
);
}
@Override
public boolean hasZComponent() {
return true;
}
@Override
public boolean hasMComponent() {
return true;
}
@Override
public int getMComponentIndex() {
return 3;
}
}
//Factories
public static class CanMakeG2D implements PositionFactory {
@Override
public Class forClass() {
return G2D.class;
}
@Override
public int getCoordinateDimension() {
return 2;
}
@Override
public G2D mkPosition(double... coordinates) {
return (coordinates.length == 0 ? new G2D() : new G2D( coordinates[0], coordinates[1] ));
}
@Override
public boolean hasZComponent() {
return false;
}
@Override
public boolean hasMComponent() {
return false;
}
@Override
public int getMComponentIndex() {
return -1;
}
}
public static class CanMakeG2DM implements PositionFactory {
@Override
public Class forClass() {
return G2DM.class;
}
@Override
public int getCoordinateDimension() {
return 3;
}
@Override
public G2DM mkPosition(double... coordinates) {
return coordinates.length == 0 ? new G2DM() : new G2DM( coordinates[0], coordinates[1], coordinates[2] );
}
@Override
public boolean hasZComponent() {
return false;
}
@Override
public boolean hasMComponent() {
return true;
}
@Override
public int getMComponentIndex() {
return 2;
}
}
public static class CanMakeG3D implements PositionFactory {
@Override
public Class forClass() {
return G3D.class;
}
@Override
public int getCoordinateDimension() {
return 3;
}
@Override
public G3D mkPosition(double... coordinates) {
return coordinates.length == 0 ? new G3D() : new G3D( coordinates[0], coordinates[1], coordinates[2] );
}
@Override
public boolean hasZComponent() {
return true;
}
@Override
public boolean hasMComponent() {
return false;
}
@Override
public int getMComponentIndex() {
return -1;
}
}
public static class CanMakeG3DM implements PositionFactory {
@Override
public Class forClass() {
return G3DM.class;
}
@Override
public int getCoordinateDimension() {
return 4;
}
@Override
public G3DM mkPosition(double... coordinates) {
return coordinates.length == 0 ? new G3DM() : new G3DM(
coordinates[0], coordinates[1], coordinates[2],
coordinates[3]
);
}
@Override
public boolean hasZComponent() {
return true;
}
@Override
public boolean hasMComponent() {
return true;
}
@Override
public int getMComponentIndex() {
return 3;
}
}
}