Cartesian coordinate system support (EPSG:5806)
From gvSIG CE Wiki
- Load two datasets from cartesian systems (e.g. two different UTM zones) into the same view and see if they both show up in the places where they are supposed to show up.
- Load a UTM dataset, transform it by rotating and displacing it a few thousand kilometers and verify that the data ends up in the right place and does not get projected (i.e. no distortions).
- Try the reprojection tools and make sure that they give an error message instead of crashing.
Add support for EPSG:5806 and engineering projections (not possible)
gvSIG CE currently uses an old version of GeoTools in order to manage projections. This version is 2.1.0 and was released on 2005. Since engineering versions were not supported by GeoTools in 2007, it is not possible to add support for EPSG:5806 (and engineering projections in general) mantaining the version GeoTools used by gvSIG CE.
This solution was previously discussed but was discarded because it involved a huge set of changes in order to have it working. However, after some deeper research we found that some certain implementation of ICrs implied that some methods in ICrs will be never called.
Also, some ICrs methods were needed by gvSIG code. But we found out that the gvSIG code was dead, so the implementation ICrs is simpler that we thought initially.
Finally, hardcoding the WKT (and all CRS metatada) in the implementation will allow us to keep the WKT generation (and all metadata-related tasks) just as is, since it won't be used by our implementation.
We can keep the current CRS module for the already supported CRS. Then, we add "new" CRS (that are not supported by the current implementation) using .properties files (one .properties file for each CRS, containing all the info required by gvSIG). These new CRS are always projected, their units are meters and coordinate transformations are not supported.
Here are more detailed steps:
- We create a directory with a different .properties file for each custom CRS. Each .properties file has the name, code, WKT and everything that is requested by gvSIG.
- When a CRS is going to be used in gvSIG, it is first checked if it is specified in this directory. If not, it falls back to the default behavior. This has to be done in org.gvsig.crs.CrsFactory.
- Then, we have to implement ICrs:
- IDatum getDatum(): it can return null if isProjected() returns true.
- Point2D createPoint(double x, double y): it returns the point with the coordinates sent as parameters.
- String getAbrev(): We return the EPSG code (for example, "EPSG:5806").
- String getFullCode(): We return the EPSG code (for example, "EPSG:5806").
- ICoordTrans getCT(IProjection dest): projections are not supported. Returns null.
- Point2D toGeo(Point2D pt): Return the point as is.
- Point2D fromGeo(Point2D gPt, Point2D mPt): set mPt with gPt coordinates and return mPt.
- boolean isProjected(): returns true. Thus, getDatum() is never called and units are set as meters (not degrees).
- double getScale(double minX, double maxX, double width, double dpi): it returns 1.
- Rectangle2D getExtent(Rectangle2D extent, double scale, double wImage, double hImage, double mapUnits, double distanceUnits, double dpi): it returns the extent sent as parameter.
- int getCode(): it returns the EPSG code (specified in the properties file).
- String getWkt() it returns the WKT string (specified in the properties file).
- void setTransformationParams(String sourceParams, String targetParams): simple setter.
- String getSourceTransformationParams(): simple getter.
- String getTargetTransformationParams(): simple getter.
- CrsWkt getCrsWkt(): returns a subclass of CrsWkt that overrides all methods in order to return the values specified in the properties file.
- CrsProj getCrsProj(): returns null. It is only used in COperation and, if it's null, no transformation is performed.
- String getProj4String(): it returns an empty string, as specified in the here. It is only used for user display.
NOTE: The .properties files are expected to be created by developers and not users. Also, they are not strictly necessary and, in order to minimize the working hours, it is possible to hardcode those values in a single class (Epsg5806). This reduces the task but removes the possibility to add more "custom" CRS easily.
Also, we would need to throw some exception for reprojection related methods and manage them at higher levels in order to tell the user that the CRS does not support coordinate transformations instead of crash or have unexpected behavior. Note that this involves changes in some interfaces and classes (throws WhateverCRSException) that will lead to lots of compilation errors that have to be fixed.
- It only adds new behavior for the custom CRS we add, one by one.
- It does not modify the previous behavior for already supported CRS. Thus, we minimize the risk of break an existing component.
- It involves the minimum changes required in order to make EPSG:5806 available. Thus, it is faster and less bug prone.
- It has several limitations: (always projected, always meters as units, coordinate transformations unsupported).
- It only supports some specific CRS (added one by one, by hand).
- It is probably the dirtiest hack ever.
Use cases compliance
A prototype has been developed in order to test the viability of this solution. It has produced the following results.
- The first use case works as expected.
- The second use case works for the following operations:
- Displace a vector layer
- Flip a raster layer
- The third use case fails: in several cases the program crashes when trying to perform coordinate transformations involving the "custom" EPSG:5806 CRS.
Upgrade GeoTools version and replace projection module
Some tests have been made (locally) with the code from the code-sprint branch and it accepts EPSG:5806. However, some dirty hacks were made. Thus, the support for EPSG:5806 won't be immediate and we haven't estimated yet how much work it would be.
Also, the estimation for the estabilization of these changes were 30 more hours (rough estimation). A lot of changes result in a lot of testing.
- Change projection module (30h, already done)
- Add support for EPSG:5806 after changing projection module. (?)
- Estabilization of the changes (30h, very rough estimation. It should be estimated also by testers)
- TOTAL: (60+ h, very rough estimation, 30h already done).
- It updates the GeoTools version to the newest version. Thus, it supports not only EPSG:5806 but everything is supported in the newest version.
- All the components that will be created/adapted could be reused by gvtools.
- It is a big change. It will require a big amount of work (for both developers and testers).
There are some actions that have to be performed, despite the implementation:
- Correct the graphic user interface so it takes into account that some CRS may not have a datum or ellipsoid:
- Info CRS panel
- New/Edit CRS in Custom CRS panel.
NOTE: If we go for the implement org.gvsig.crs.ICrs solution, it won't be necessary to change the DefaultGeodeticDatum casts since they only appear in libJCRS on classes that are not used by our solution (subclass full overrided or interface fully implemented by ourselves) and in extJCRS on panels that don't appear if the CRS has no datum or ellipsoid.
We have two different solutions that may work and that suits better on different stages of the gvSIG CE roadmap:
- Implement org.gvsig.crs.ICrs. It is a short and cheap. However, it is less sustainable because it adds more code and different behaviour to the already convoluted CRS module in gvSIG CE. It may work good in the short term (gvSIG CE 1.0)
- Upgrade GeoTools version and replace projection module. It is longer, harder and more expensive. However, it is more sustainable since all the CRS operations are done by GeoTools and we reduce the amount of lines of code. Also, the result of this solution can be also used by gvtools.