मैं जियोटूल के साथ एक नक्शा बनाना चाहता हूं और इसे एक छवि (जैसे जेपीईजी) में सहेजना चाहता हूं। मेरी आवश्यकताएं सरल हैं:
- 2 परतों के साथ दुनिया का एक नक्शा बनाएँ: राजनीतिक सीमाएँ और एक स्थैतिक। परतें विभिन्न स्रोतों और विभिन्न अनुमानों से हैं।
- विभिन्न अनुमानों के लिए मानचित्र को आउटपुट करें (जैसे "EPSG: 5070", "EPSG: 4326", "EPSG: 54012", "EPSG: 54009", आदि)
- आउटपुट को अलग-अलग AOI (जैसे -124.79 से -66.9 लोन, 24.4 से 49.4 लैट) पर क्लिप करें।
मैं इस प्रोग्राम को एपीआई के माध्यम से करना चाहता हूं। अब तक, मुझे सीमित सफलता मिली है। मैंने इस दृष्टिकोण का उपयोग करके विभिन्न अनुमानों में एक नक्शा और आउटपुट बनाना सीखा है:
//Step 1: Create map
MapContent map = new MapContent();
map.setTitle("World");
//Step 2: Set projection
CoordinateReferenceSystem crs = CRS.decode("EPSG:5070"); //Conic projection over US
MapViewport vp = map.getViewport();
vp.setCoordinateReferenceSystem(crs);
//Step 3: Add layers to map
CoordinateReferenceSystem mapCRS = map.getCoordinateReferenceSystem();
map.addLayer(reproject(getPoliticalBoundaries(), mapCRS));
map.addLayer(reproject(getGraticules(), mapCRS));
//Step 4: Save image
saveImage(map, "/temp/graticules.jpg", 800);
सेव विधि जियोटूलस वेबसाइट से सीधी है :
public void saveImage(final MapContent map, final String file, final int imageWidth) {
GTRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
Rectangle imageBounds = null;
ReferencedEnvelope mapBounds = null;
try {
mapBounds = map.getMaxBounds();
double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0);
imageBounds = new Rectangle(
0, 0, imageWidth, (int) Math.round(imageWidth * heightToWidth));
} catch (Exception e) {
// failed to access map layers
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_INT_RGB);
Graphics2D gr = image.createGraphics();
gr.setPaint(Color.WHITE);
gr.fill(imageBounds);
try {
renderer.paint(gr, imageBounds, mapBounds);
File fileToSave = new File(file);
ImageIO.write(image, "jpeg", fileToSave);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
पुनर्विचार विधि मेरा आविष्कार है। यह एक हैक का एक सा है, लेकिन इसका एक ही तरीका है कि मैं एक विशिष्ट प्रक्षेपण के लिए एक छवि उत्पादन करने के लिए मिल सकता है।
private static Layer reproject(Layer layer, CoordinateReferenceSystem mapCRS) throws Exception {
SimpleFeatureSource featureSource = (SimpleFeatureSource) layer.getFeatureSource();
//Define coordinate transformation
CoordinateReferenceSystem dataCRS = featureSource.getSchema().getCoordinateReferenceSystem();
boolean lenient = true; // allow for some error due to different datums
MathTransform transform = CRS.findMathTransform(dataCRS, mapCRS, lenient);
//Create new feature collection
SimpleFeatureCollection copy = FeatureCollections.newCollection("internal");
SimpleFeatureType featureType = SimpleFeatureTypeBuilder.retype(featureSource.getSchema(), mapCRS);
SimpleFeatureIterator iterator = featureSource.getFeatures().features();
try {
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Geometry geometry = (Geometry) feature.getDefaultGeometry();
Geometry geometry2 = JTS.transform(geometry, transform);
copy.add( SimpleFeatureBuilder.build( featureType, new Object[]{ geometry2 }, null) );
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
iterator.close();
}
//Return new layer
Style style = SLD.createLineStyle(Color.BLACK, 1);
layer = new FeatureLayer(copy, style);
layer.setTitle("Graticules");
return layer;
}
आउटपुट वास्तव में खराब है:
इसलिए, मुझे लगता है कि मेरे पास कुछ अलग सवाल हैं:
- क्या यह सही दृष्टिकोण है? क्या मुझे वास्तव में परतों को मैन्युअल रूप से रद्द करने की आवश्यकता है या क्या MapViewport मेरे लिए ऐसा करने वाला है?
- मैं किसी विशिष्ट AOI को आउटपुट कैसे क्लिप करूं? मैंने MapViewport.setBounds (लिफ़ाफ़े) विधि का उपयोग करके सीमा निर्धारित करने की कोशिश की है, लेकिन saveImage विधि सीमा की उपेक्षा करती है।
- आर्क्स के रूप में रेंडर करने के लिए मुझे अपनी अक्षांश रेखाएँ कैसे मिलेंगी? क्या कोई परिवर्तन सेटिंग है जो मुझे याद आ रही है?
मैं जियोटूल 8.7 का इस्तेमाल कर रहा हूं।