I am using geotools to display a map, convert the map coordinates to screen coordinates, and export it back out as an SVG file. So far everything works fine, however I have run into two issues I could use assistance with. (Note: I cannot display any maps I am using due to confidentiality agreements)
- Some lines on the map, after conversion, are missing (segments and whole lines).
- The map is inverted (upside down).
The bigger issue is the first one, but I am not sure what is causing it (no errors or exceptions). Could be line conversion code or loading the map. I will post my line conversion code and my attempt to correct the inverted code.
Also the map is based in Michigan, which could be causing this issue (I am not a map/geotools expert).
// Converts map lines to fit in smaller window (mainly for Adobe Illustrator)
private ArrayList<FeatureLine> convertLines(ArrayList<FeatureLine> lines) {
ArrayList<FeatureLine> convertedCoords = new ArrayList();
try {
Rectangle imageBounds = jFrame.getBounds();
ReferencedEnvelope mapBounds = map.getMaxBounds();
AffineTransform world2screen = createTransform(mapBounds, imageBounds);
for (FeatureLine coord : lines) {
Point2D screenCoordStart = world2screen.transform(coord.StartPoint, null);
Point2D screenCoordEnd = world2screen.transform(coord.EndPoint, null);
if (coord.StartPoint.x != 0.0) {
convertedCoords.add(new FeatureLine(screenCoordStart, screenCoordEnd));
}
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error occured while converting lines", ex);
}
return convertedCoords;
}
Inverts map
//Invert map to look normal (doesnt work).
System.setProperty("org.geotools.referencing.forceXY", "true");
This could work, but I'm not sure where to use the CRS
// Inverts map
Hints hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory("EPSG", hints);
CoordinateReferenceSystem crs = factory.createCoordinateReferenceSystem("EPSG:4326");
Loading the map
// Load shapefile into JMapFrame
protected void loadFile(File shapeFile) throws IOException {
URL shape = shapeFile.toURI().toURL();
ShapefileDataStore ds = null;
try {
FileDataStore store = FileDataStoreFinder.getDataStore(shape);
featureSource = store.getFeatureSource();
ds = new ShapefileDataStore(shape);
FeatureSource<SimpleFeatureType, SimpleFeature> fs = ds.getFeatureSource();
Hints hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory("EPSG", hints);
CoordinateReferenceSystem crs = factory.createCoordinateReferenceSystem("EPSG:4326");
collection = fs.getFeatures();
featureArrayS = featuresList();
map = new MapContent();
Style style = SLD.createSimpleStyle(featureSource.getSchema());
//Style style = createStyle(shape, featureSource);
Layer layer = new FeatureLayer(featureSource, style);
map.addLayer(layer);
System.out.println("File name: " + shapeFile.getName());
jframe.setTitle("File: " + shapeFile.getName());
String layerName = "Default";
layer.setTitle(layerName);
layerList.add(layer);
jframe.setMapContent(map);
} catch (IOException | FactoryRegistryException | FactoryException ex) {
logger.log(Level.SEVERE, "", ex);
} finally {
if (ds != null) {
ds.dispose();
}
}
}
Here is an example to explain Michigan's CRS.
Update: 3/31/2017
This one shows the inverted output of the map, the inverted map being on the left, while the correct (and desired) output is on the right.
This shows a zoomed in picture of the missing lines, incorrect output on the left, and correct (expected) output on the right.
Here is the CRS for the map:
PROJCS["NAD_1983_Hotine_Oblique_Mercator_Azimuth_Natural_Origin",
GEOGCS["GCS_North_American_1983",
DATUM["D_North_American_1983",
SPHEROID["GRS_1980", 6378137.0, 298.257222101]],
PRIMEM["Greenwich", 0.0],
UNIT["degree", 0.017453292519943295],
AXIS["Longitude", EAST],
AXIS["Latitude", NORTH]],
PROJECTION["Hotine_Oblique_Mercator"],
PARAMETER["longitude_of_center", -86.0],
PARAMETER["latitude_of_center", 45.30916666666666],
PARAMETER["azimuth", 337.25555999999995],
PARAMETER["scale_factor", 0.9996],
PARAMETER["false_easting", 2546731.496],
PARAMETER["false_northing", -4354009.816],
PARAMETER["rectified_grid_angle", 337.25555999999995],
UNIT["m", 1.0],
AXIS["x", EAST],
AXIS["y", NORTH]]
Lastly, I obtained this map data from here: