different CRS on a Map

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

different CRS on a Map

"Ludwig Moser-Spitzenstätter"
Dear NG

when i create a MapContent with a given CRS (lets say EPSG:3857)
and want to add a Layer containing data which is based on another CRS (for example EPSG:4326 - WGS84)
in my test the loaded shapefile comes up on the wrong position and totally wrong size (in the example above the wgs84 data is located at 0.0 in the mercator, obviously because the data has completely different values)

do i need to transform the data by hand (like in this tutorial http://docs.geotools.org/stable/userguide/tutorial/geometry/geometrycrs.html)

or is there a Simple way to enable automatic transformation?
how do i transform a DirectLayer/Image/GeoTiff?

if each layer has information about its own crs and the map has information about the rendered CRS it should be possible to automatically transform the data - right?

i hope i was clear in what i have to do and what i tried.

thanks in advance
Ludwig Moser-Spitzenstätter

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
GeoTools-GT2-Users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
Reply | Threaded
Open this post in threaded view
|

Re: different CRS on a Map

Ian Turton
can you include a short code example which shows the problem, you may need to include a link to some example data too.

Ian

On 1 June 2017 at 08:32, "Ludwig Moser-Spitzenstätter" <[hidden email]> wrote:
Dear NG

when i create a MapContent with a given CRS (lets say EPSG:3857)
and want to add a Layer containing data which is based on another CRS (for example EPSG:4326 - WGS84)
in my test the loaded shapefile comes up on the wrong position and totally wrong size (in the example above the wgs84 data is located at 0.0 in the mercator, obviously because the data has completely different values)

do i need to transform the data by hand (like in this tutorial http://docs.geotools.org/stable/userguide/tutorial/geometry/geometrycrs.html)

or is there a Simple way to enable automatic transformation?
how do i transform a DirectLayer/Image/GeoTiff?

if each layer has information about its own crs and the map has information about the rendered CRS it should be possible to automatically transform the data - right?

i hope i was clear in what i have to do and what i tried.

thanks in advance
Ludwig Moser-Spitzenstätter

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
GeoTools-GT2-Users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users




--
Ian Turton

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
GeoTools-GT2-Users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
Reply | Threaded
Open this post in threaded view
|

Re: different CRS on a Map

"Ludwig Moser-Spitzenstätter"
In reply to this post by "Ludwig Moser-Spitzenstätter"
i hope my mail is not too confusing and my english is ok. (not my mother tongue)

I am no more sure that i understand what to do with geotools. i do know what has to be done in real world and what i expect geotools to do (obviously this does not match up ;-) )
I thought it needs a CRS to be specified (for each layer, so GeoTools knows the Source CRS)
The MapContent has a CRS specified, in which the data will be represented/transformed to.
Isnt it independent which CRS i do use to render – the data should always be the same place – on the map?
I mean if points are on the same ‚actual place‘ it does not matther which CRS i have the data stored in. (ignoring the errors of transformation from one CRS to the other)

I looked at some tutorials, but i rarely see how to specify the source datas CRS (there are factories and builders, but most of em are never ‚simply‘ created via their constructor. they are retrieved via some Util Classes.

Here an example of my UpdateableLayer
Which shall accept Points and store them as wgs84; which is working fine, but when i change the CRS of the Map, the Points are ‚gone‘ as their CRS is not set!
When i uncomment the outcommented lines, its transforming to the new CRS. BUT this is ‚Hacking‘ with reflection.
How can this be done correct?

public class UpdateableLayer
extends FeatureLayer {
private DefaultFeatureCollection featureCollection;
private GeometryFactory geometryFactory;
private SimpleFeatureBuilder featureBuilder;
// private CoordinateReferenceSystem crs;

// index of points
private int val = 0;
private static boolean debug = true;

/**
* @param coordinateReferenceSystem
* @param collection
* @param featureBuilder
* @param style
* Style style = SLD.createPointStyle("circle", Color.BLUE,
* Color.BLUE, 1.0f, 5.0f);
*/
public UpdateableLayer(CoordinateReferenceSystem crs, FeatureCollection collection,
SimpleFeatureBuilder featureBuilder, Style style) {
super(collection, style);
this.featureCollection = (DefaultFeatureCollection) collection;
this.featureBuilder = featureBuilder;
// this.crs = crs;
// GisMapUtils.forceCRS(featureBuilder.getFeatureType(), crs);
// GisMapUtils.forceCRS(getFeatureSource().getSchema(), crs);
init();
}

// TODO: this is not correct
public ReferencedEnvelope getBounds() {
return super.getBounds();
}

private void init() {
geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
}

public void updated() {
fireMapLayerListenerLayerChanged(MapLayerEvent.DATA_CHANGED);
}

public void addPointFeature(CoordinateReferenceSystem coordinateReferenceSystem, double x, double y) {
try {
CoordinateReferenceSystem crs = getBounds().getCoordinateReferenceSystem();
double[] transformedCoords = GeoToolsUtil.transform(coordinateReferenceSystem, crs, x, y);
Coordinate pos = new Coordinate(transformedCoords[0], transformedCoords[1]);
if (debug)
System.out.println(String.format("adding PointFeature to (%s|%s)", pos.x, pos.y));
val++;
featureCollection.add(createFeature(featureBuilder, pos, val));
} catch (MismatchedDimensionException e) {
e.printStackTrace();
} catch (TransformException e) {
e.printStackTrace();
} catch (FactoryException e) {
e.printStackTrace();
}

if (debug) {
System.out.println("featureCollection.size() = " + featureCollection.size());
SimpleFeatureIterator iterator = featureCollection.features();
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
System.out.println(String.format("feature = %s", feature));
}
}
}

private SimpleFeature createFeature(SimpleFeatureBuilder featureBuilder, Coordinate pos, int id) {
com.vividsolutions.jts.geom.Point p = geometryFactory.createPoint(pos);
featureBuilder.add(p);
featureBuilder.add(id);

// null arg means allow the builder to generate a default feature ID
return featureBuilder.buildFeature(null);
}
}



When i create the Layer i pass those values:
Note that the typeBuilder is set to coordinateReferenceSystem, which is Wgs84 in my calls

public static UpdateableLayer createInteractiveUserLayer(CoordinateReferenceSystem coordinateReferenceSystem) {
System.out.println(String.format("Create an UpdateableLayer with CRS: %s", coordinateReferenceSystem.getName()));
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
try {
typeBuilder.setCRS(coordinateReferenceSystem);
} catch (Exception e) {
System.err.println("FAILED TO SET CRS TO WGS84");
} // WGS84
typeBuilder.setName("points");
// typeBuilder.add("geometry", Point.class, DefaultGeographicCRS.WGS84);
typeBuilder.add("geometry", Point.class, coordinateReferenceSystem);
typeBuilder.add("id", Integer.class);
// typeBuilder.add("guid", String.class);
// add further shp infos
SimpleFeatureType featureType = typeBuilder.buildFeatureType();
FeatureCollection featureCollection = new DefaultFeatureCollection(featureCollectionId, featureType);
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
Style pointStyle = SLD.createPointStyle("Circle", Color.red, Color.green, 1f, 3f);

UpdateableLayer layer = new UpdateableLayer(coordinateReferenceSystem, featureCollection, featureBuilder,
pointStyle);
layer.setTitle("Interactive User Layer");
return layer;
}

























I am not sure if i was able to work it out as needed;
i created a small snippet of what i include in my 'bigger' application.
NOTE: in my bigger application i use the SWT version! I needed to modify the code from unsupported modules to get started - did not work out of the box here.
The snippet is based on a swing version.

i put the example files online at:
http://lumo.linkpc.net/geotools/
provinces.zip -- a shapefile with provinces of europe
geotools_example_viewer-min.zip - the example viewer, without the geotools libraries (i currently use 15.1)

you will have to adapt the path to the shp file in code (hardcoded)

in the SampleMapApp there is a switch
boolean useWGS84 = true; // use wgs84 if true, otherwise use pseudo-mercator
the example viewer loads a WMS and the SHP file
the Shapefile does not show up if the CRS is not set to wgs84
the WMS is displayed wrong if its set to wgs84

NOTE: how do you specify the CRS for a ShapeFile?
i created a workaround to set the crs for the ShapeFile - this solves 'some' issues i have in my 'bigger' application, but its not a clean solution

public static void addSHP(MapContent mapContent, String shpFile) {
File openFile = new File(shpFile);
FileDataStore store;
try {
store = FileDataStoreFinder.getDataStore(openFile);
SimpleFeatureSource featureSource = store.getFeatureSource();
forceCRS(featureSource.getSchema(), MyGisUtils.getWgs84()); // <-- this is my workaround
Style style = org.geotools.swt.utils.Utils.createStyle(openFile, featureSource);
FeatureLayer featureLayer = new FeatureLayer(featureSource, style);
featureLayer.setVisible(true);
featureLayer.setTitle(openFile.getName().substring(0, openFile.getName().length() - ".shp".length()));
mapContent.addLayer(featureLayer);
} catch (IOException e) {
System.err.println("failed to add shapefile");
e.printStackTrace();
}
}


public static void forceCRS(SimpleFeatureType type, CoordinateReferenceSystem forcedCRS) {
if (type instanceof FeatureTypeImpl) {
Field crs;
try {
crs = FeatureTypeImpl.class.getDeclaredField("crs");
crs.setAccessible(true);
crs.set(type, forcedCRS);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

If possible could you provide me a small example where:
MapContent CRS = Mercator
+ wms layer (these use Mercator)
+ ShapeFile is added using WGS84 (EPSG: 4326)

And the shapefile is properly displayed on the Map?
I worked out how to create my own custom layers with data in WGS84, but transformation is not working properly – same problem like the shapefiles (if Map is displayed in Mercator)
If i set the Map to WGS84 (EPSG 4326) the Images get reprojected and they look really unsharp and ugly.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
GeoTools-GT2-Users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users