Paul You wrote: "The key is to make the interfaces as simple as possible so as to make it easy for people to use and re-use them. I would also not use abstract base classes, instead I would have concrete classes that can be parameterized for different implementations of that Projection (e.g. there would be a say UTM class that would be parameterized on the UTM zone rather than a UTM11, UTM10 classes). I would at a higher level have some kind of factory that given a SRID would return the appropriate implementation for end users to use."
Good point. There is no reason we couldn't use concrete classes with a class to capture common parameters. For example, a common UTM spatial reference transformation class with a UTM zone parameter class. You wrote: "For your point 4 regarding the intermediate format, I do agree on this in principal but not necessarily using the same approach. My vision would be to support this via Chained operations. For example to go from BC Albers (srid 3005, NAD83) to UTM Zone 10(srid 26910. NAD83) I would have a chained operation consisting of BcAlbersToGeographics and GeographicsToUTM(10). Now if you wanted to change between Ellipsoid then you may have in the middle say a WGS84ToNAD83 operation in the middle." Let me tell you what I don't like about this approach: It forces the client code to determine which transformations need to go into the chain. In my very humble opinion this makes end use of the library more complicated. I like it better when this logic is hidden from the end user. I think we could still implement the "chained operations" concept, but as helper classes not as part of the exposed API. In other words, leave the simpe to and from methods in the main transformation interface but make the chained operation classes and interfaces available to implementers of the interface. This perserves the simplicity and gives implementers the most flexibility. I also think we need to use something more specific than a generic geographic coordinate system as our "in-between" spatial reference system. The more specific we can be about this system the easier it will be to get to and from it. The Sunburned Surveyor On 9/10/07, Paul Austin <[EMAIL PROTECTED]> wrote: > Michael, > > I avoided the return type as I don't want to have the extra object > creation, I consider the double[] array parameter to be a temporary > array used just for the one or more operations, rather than the actual > storage of the ordinates. By this I mean when calling an operation you > must expect the values of that array to change. If you don't want that > then create another array before calling the operation. > > I would probably also use a List<CoordinateOperation> internally within > the ChainedOperation class but provide constructors for the array and > List forms. > > Paul > > > Michaël Michaud wrote: > > Hi Paul, > > > > That's close to what I can imagine. > > Can you explain why you choosed to return void instead of double[]. To > > avoid object creation ? > > Returning a double[] would have been clearer for me, but may be > > returning void is more efficient... > > > > getInverseOperation is not limited to Projection. Datum transformation > > (usually translation or helmert transformation) are also invertible (in > > the general case). May be getInverseOperation should be available in the > > main CoordinateOperation interface along with a boolean isInvertible > > method. In fact, I don't know exactly why we should use a > > getInverseOperation from a CoordinateOperation instead of implementing > > and instanciating the inverseOperation as a first class object. > > > > I like ChainedOperation. > > My version used a List instead of an array, but I'm ok with an array. > > > > Michael > > > > Paul Austin a écrit : > > > > > >> How about the following interface? The ordinates array has the same > >> semantics as ordinates in a JTS CoordinateSequence. The values in the > >> ordinates array are modified in place by the CoordinateOperation. > >> > >> public interface CoordinateOperation { > >> void perform(double[] ordinates); > >> } > >> > >> For projections you may have an interface such as the following as a > >> convenience to get both the forward and inverse operations. > >> > >> public interface Projection { > >> CoordinateOperation getOperation(); > >> CoordinateOperation getInverseOperation(); > >> } > >> > >> A chained operation may look like the following. > >> > >> public class ChainedOperation implements CoordinateOperation { > >> private CoordinateOperation[] operations; > >> > >> public void perform(double[] ordinates) { > >> for (CoordinateOperation operation : operations) { > >> operation.perform(ordinates; > >> } > >> } > >> } > >> > >> Paul > >> > >> Paul Austin wrote: > >> > >> > >> > >>> I've come up with a very simple interface for projection algorithms. The > >>> purpose of this is to be model neutral (not tied to JTS), as such it is > >>> not for use by end users but instead for use in higher level libraries > >>> that would work on JTS geometries. > >>> > >>> public interface Projection { > >>> void forward(); > >>> > >>> void reverse(); > >>> > >>> double getX(); > >>> void setX(double x); > >>> > >>> double getY(); > >>> void setY(double y); > >>> > >>> } > >>> > >>> > >>> To perform a forward projection the code would be as follows. > >>> > >>> projection.setX(lonDegrees); > >>> projection.setY(latDegrees); > >>> projection.forward(); > >>> x = projection.getX(); > >>> y = projection.getY(); > >>> > >>> > >>> > >>> Reverse projection would be similar. > >>> > >>> projection.setX(xMetres); > >>> projection.setY(yMetres); > >>> projection.reverse(); > >>> lonDegrees = projection.getX(); > >>> latDegrees = projection.getY(); > >>> > >>> NOTE: The interface is not thread safe. > >>> > >>> The design goals were it must be simple and not require any temporary > >>> objects. > >>> > >>> A JTS wrapper for this would have the following two basic methods > >>> > >>> > >>> public Coordinate forward(double x, double y, double z) { > >>> projection.setX(x); > >>> projection.setY(y); > >>> projection.forward(); > >>> Coordinate coordinate = new Coordinate(projection.getX(), > >>> projection.getY(),z); > >>> forwardPrecisionModel.makePrecise(coordinate); > >>> return coordinate; > >>> } > >>> > >>> public Coordinate reverse(double x, double y, double z) { > >>> projection.setX(x); > >>> projection.setY(y); > >>> projection.reverse(); > >>> Coordinate coordinate = new Coordinate(projection.getX(), > >>> projection.getY(),z); > >>> reversePrecisionModel.makePrecise(coordinate); > >>> return coordinate; > >>> } > >>> > >>> plus a number of other methods to deal with all the JTS Geometry types, > >>> see attached for full implementation. Note that there could be a > >>> performance optimization for coordinate sequences to directly deal with > >>> the Projection interface. > >>> > >>> Most projections go to/from Geographics to a Cartesian system to go from > >>> one Cartesian to another Cartesian you would need a chained projection > >>> which goes from one to another. > >>> > >>> The last piece in the puzzle is to have a ProjectionFactory that can > >>> create projections from EPSG srid codes. There can be many factory > >>> implementations, e.g. one to wrap FME, one to wrap the Java Projection > >>> Library, one for JUMP specific projections and one for GeoTools. You > >>> would then interact with an instance of the factory to create your > >>> projections and then use either the Projection interface or the > >>> JtsProjection wrapper. > >>> > >>> What do you guys think? > >>> > >>> Paul > >>> > >>> ------------------------------------------------------------------------ > >>> > >>> ------------------------------------------------------------------------- > >>> This SF.net email is sponsored by: Splunk Inc. > >>> Still grepping through log files to find problems? Stop. > >>> Now Search log events and configuration files using AJAX and a browser. > >>> Download your FREE copy of Splunk now >> http://get.splunk.com/ > >>> ------------------------------------------------------------------------ > >>> > >>> _______________________________________________ > >>> Jump-pilot-devel mailing list > >>> Jump-pilot-devel@lists.sourceforge.net > >>> https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel > >>> > >>> > >>> > >> ------------------------------------------------------------------------- > >> This SF.net email is sponsored by: Microsoft > >> Defy all challenges. Microsoft(R) Visual Studio 2005. > >> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > >> _______________________________________________ > >> Jump-pilot-devel mailing list > >> Jump-pilot-devel@lists.sourceforge.net > >> https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel > >> > >> > >> > >> > >> > > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio 2005. > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > > Jump-pilot-devel mailing list > > Jump-pilot-devel@lists.sourceforge.net > > https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel > > > > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2005. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Jump-pilot-devel mailing list > Jump-pilot-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel > ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Jump-pilot-devel mailing list Jump-pilot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel