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 [email protected] https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
