/** * Implementation of the transform method for a sequence of transformation. * It is important that input coordinate is a 3D coordinate because any of * the coordinate operation of the sequence may be a 3D coordinate of * {@link org.cts.op.CoordinateOperation}s. * * @param coord the 3D coord to transform * @return * @throws IllegalCoordinateException if <code>coord</code> is not * compatible with this <code>CoordinateOperation</code>. * @throws org.cts.op.CoordinateOperationException */ @Override public double[] transform(double[] coord) throws IllegalCoordinateException, CoordinateOperationException { for (CoordinateOperation op : sequence) { coord = op.transform(coord); } return coord; }
/** * Create a new InterpolationMethodException. * * @param op the interpolation method */ public NonInvertibleOperationException(CoordinateOperation op) { super("" + op.getName() + " is not invertible"); } }
@Override public double getPrecision() { // Precision of this iterative operation is difficult to guess // because we don't know it uses radians, degrees or meters // We just suppose it is less than the base transformation return op.getPrecision()/2.0; }
List<CoordinateOperation> result = new ArrayList<CoordinateOperation>(); for (CoordinateOperation op : sequence) { if (op != null && !op.isIdentity() && !(op instanceof CoordinateOperationSequence)) { result.add(op); } else if (op instanceof CoordinateOperationSequence) { CoordinateOperation op = result.get(i); try { if (op.inverse().equals(result.get(i-1))) { result.remove(i); result.remove(i-1);
private void addGeographicTransformation(GeodeticDatum targetDatum, CoordinateOperation coordOp, boolean addInverseOp) { if (geographicTransformations.get(targetDatum) == null) { geographicTransformations.put(targetDatum, new HashSet<CoordinateOperation>()); } else if (geographicTransformations.get(targetDatum).contains(coordOp)) return; geographicTransformations.get(targetDatum).add(coordOp); if (addInverseOp) { try { targetDatum.addGeographicTransformation(this, coordOp.inverse(), false); } catch (NonInvertibleOperationException e) { e.printStackTrace(); } } }
/** * This method can identify sequences with no operations as equivalent to * Identity, but it does not try to nullify sequences of two opposite * operations. * @return true if this operation does not change coordinates. */ public boolean isIdentity() { for (CoordinateOperation op : sequence) { if (!op.isIdentity()) return false; } return true; } }
for (CoordinateOperation op1 : getGeographicTransformations(WGS84)) { for (CoordinateOperation op2 : targetDatum.getGeographicTransformations(WGS84)) { if (op1.equals(op2) || (op1.isIdentity() && op2.isIdentity())) { addGeographicTransformation(targetDatum, Identity.IDENTITY, true); } else { addGeographicTransformation(targetDatum, new GeocentricTransformationSequence( new Identifier(CoordinateOperation.class), op1, op2.inverse()), true);
@Override public GeocentricTransformation inverse() throws NonInvertibleOperationException { CoordinateOperation[] inverse_sequence = new CoordinateOperation[sequence.length]; for (int i = 0; i < sequence.length; i++) { // If one of the CoordinateOperation is not invertible, it // will throw a NonInvertibleOperationException. inverse_sequence[sequence.length - i - 1] = sequence[i].inverse(); //if (inverse_sequence[sequence.length-i-1] == null) return null; } return new GeocentricTransformationSequence(getIdentifier(), inverse_sequence, precision); }
/** * Returns true if o is also an Identity CoordinateOperation. * * @param o The object to compare this ProjectedCRS against */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o instanceof CoordinateOperation) { return ((CoordinateOperation)o).isIdentity(); } return false; }
@Override public void filter(Coordinate coord) { try { if (Double.isNaN(coord.z)) { coord.z = 0; } double[] xyz = coordinateOperation .transform(new double[]{coord.x, coord.y, coord.z}); coord.x = xyz[0]; coord.y = xyz[1]; if (xyz.length > 2) { coord.z = xyz[2]; } else { coord.z = Double.NaN; } } catch (CoordinateOperationException |IllegalCoordinateException ex) { Logger.getLogger(ST_Transform.class.getName()).log(Level.SEVERE, null, ex); } }
/** * Return a pessimistic estimation of the precision where precision * of every sub-operation is simply added to the previous. * @return */ public double getPrecision() { double combinedPrecision = 0.0; for (CoordinateOperation op : sequence) { combinedPrecision += op.getPrecision(); } return combinedPrecision; }
|| op1.equals(op2.inverse())) { lst1.remove(lst1.size() - 1); lst2.remove(0);
/** * Returns true if o is equals to <code>this</code>. * GeocentricTranslations are equals if they both are identity, or * if all their parameters are equal. * * @param o The object to compare this ProjectedCRS against */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o instanceof CoordinateOperation) { if (this.isIdentity() && ((CoordinateOperation)o).isIdentity()) { return true; } if (o instanceof GeocentricTranslation) { GeocentricTranslation gt = (GeocentricTranslation) o; return ((this.tx == gt.tx) && (this.ty == gt.ty) && (this.tz == gt.tz)); } } return false; }
GeocentricTransformationSequence newSequence = new GeocentricTransformationSequence( new Identifier(CoordinateOperation.class, source.getCode() + " to " + target.getCode() + " through " + datumTransformation.getName()), source.toGeographicCoordinateConverter(), new LongitudeRotation(source.getDatum().getPrimeMeridian().getLongitudeFromGreenwichInRadians()), } catch (NonInvertibleOperationException e) { LOG.warn("Operation from " + source.getCode() + " to " + target.getCode() + " through " + datumTransformation.getName() + " could not be created"); LOG.error("CoordinateOperationFactory", e); opList.add(new CoordinateOperationSequence( new Identifier(CoordinateOperationSequence.class, source.getCode() + " to " + target.getCode() + " through " + datumTf.getName()), source.toGeographicCoordinateConverter(), datumTf, } catch (NonInvertibleOperationException e) { LOG.warn("Operation from " + source.getCode() + " to " + target.getCode() + " through " + datumTf.getName() + " could not be created"); LOG.error("CoordinateOperationFactory", e);
@Override public double[] transform(double[] coord) throws IllegalCoordinateException, CoordinateOperationException { boolean iter = false; int count = 0; for (int i = 0; i < realValueIndex.length; i++) { iter = iter || Math.abs(coord[realValueIndex[i]] - coord[calculatedValueIndex[i]]) > tolerance[i]; } while (iter) { coord = op.transform(coord); iter = false; for (int i = 0; i < realValueIndex.length; i++) { iter = iter || Math.abs(coord[realValueIndex[i]] - coord[calculatedValueIndex[i]]) > tolerance[i]; } if (++count > maxIterations ) throw new TooManyIterationsException(this, count); } return coord; }
/** * Returns the most precise among the list of {@link org.cts.op.CoordinateOperation}s. * @param ops * @return */ public static CoordinateOperation getMostPrecise(Collection<? extends CoordinateOperation> ops) { CoordinateOperation preciseOp = null; double currentPrecision = Double.MAX_VALUE; for (CoordinateOperation op : ops) { if (op.getPrecision() < currentPrecision) { preciseOp = op; currentPrecision = op.getPrecision(); } } return preciseOp; }
/** * Creates the inverse CoordinateOperation. * @return * @throws org.cts.op.NonInvertibleOperationException */ @Override public CoordinateOperation inverse() throws NonInvertibleOperationException { CoordinateOperation[] inverse_sequence = new CoordinateOperation[sequence.length]; for (int i = 0; i < sequence.length; i++) { // If one of the CoordinateOperation is not invertible, it // will throw a NonInvertibleOperationException. inverse_sequence[sequence.length - i - 1] = sequence[i].inverse(); //if (inverse_sequence[sequence.length-i-1] == null) return null; } return new CoordinateOperationSequence(getIdentifier(), inverse_sequence, precision); }
/** * Returns true if o is equals to <code>this</code>. * SevenParametersTransformations are equals if they both are identity, or * if all their parameters are equal. * * @param o The object to compare this ProjectedCRS against */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o instanceof CoordinateOperation) { if (this.isIdentity() && ((CoordinateOperation)o).isIdentity()) { return true; } if (o instanceof SevenParameterTransformation) { SevenParameterTransformation transfo = (SevenParameterTransformation) o; return ((this.tx == transfo.tx) && (this.ty == transfo.ty) && (this.tz == transfo.tz) && (this.rx == transfo.rx) && (this.ry == transfo.ry) && (this.rz == transfo.rz) && (this.scale == transfo.scale) && (this.rotationConvention == transfo.rotationConvention) && (this.linearized == transfo.linearized)); } } return false; }
@Override public void filter(Coordinate coord) { try { if (Double.isNaN(coord.z)) { coord.z = 0; } double[] xyz = coordinateOperation .transform(new double[]{coord.x, coord.y, coord.z}); coord.x = xyz[0]; coord.y = xyz[1]; if (xyz.length > 2) { coord.z = xyz[2]; } else { coord.z = Double.NaN; } } catch (IllegalCoordinateException ice) { throw new RuntimeException("Cannot transform the coordinate" + coord.toString(), ice); } }
/** * Returns the most precise among the list of {@link org.cts.op.CoordinateOperation}s. * @param ops * @return */ public static CoordinateOperation getMostPrecise3DTransformation(Collection<? extends CoordinateOperation> ops) { CoordinateOperation preciseOp = null; double currentPrecision = Double.MAX_VALUE; for (CoordinateOperation op : ops) { if (op.getPrecision() < currentPrecision && op instanceof GeocentricTransformation) { preciseOp = op; currentPrecision = op.getPrecision(); } } return preciseOp; }