Convertir shapefile a PNG usando GeoTools

Sep 11 2020

Necesito saber cómo exportar un archivo .shp a .png en Java usando geotools.

Encontré un ejemplo aquí: Convertir geojson a png . Pero necesito convertir shapefile a PNG.

Respuestas

5 IanTurton Sep 11 2020 at 18:12

Para exportar cualquier tipo de característica de GeoTools a una imagen, el proceso es el mismo : lee las características (o cobertura) usando a DataStore, luego renderiza estas características usando a Style(a menudo se lee de un archivo SLD) y luego guarda la imagen de Java a un archivo usando ImageIO.

Entonces, en su caso específico, necesitará un ShapefileDatastorepero no es necesario saberlo, solo use DataStoreFinderpara buscar uno DataStoreFactoryque pueda manejar sus requisitos.

HashMap<String, Object> params = new HashMap<>();
params.put(ShapefileDataStoreFactory.URLP.key, URLs.fileToUrl(new File("/home/ian/Data/states/states.shp")));
DataStore ds = DataStoreFinder.getDataStore(params);
SimpleFeatureCollection fc = ds.getFeatureSource(ds.getTypeNames()[0]).getFeatures();

Ahora para renderizarlo:

MapContent mapContent = new MapContent();
mapContent.setTitle("Quickstart");
Style style = SLD.createSimpleStyle(features.getSchema());
Layer layer = new FeatureLayer(features, style);
mapContent.addLayer(layer);

Luego necesitamos llamar a Rendereren ese mapContent para dibujarlo en Image:

File outputFile = new File("states.png");
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
    ImageOutputStream outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);) {

  int w = 1000;
  ReferencedEnvelope bounds = fc.getBounds();
  int h = (int) (w * (bounds.getHeight() / bounds.getWidth()));
  BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
  Graphics2D g2d = bufferedImage.createGraphics();

  mapContent.getViewport().setMatchingAspectRatio(true);

  mapContent.getViewport().setScreenArea(new Rectangle(Math.round(w), Math.round(h)));
  mapContent.getViewport().setBounds(bounds);

  g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

  Rectangle outputArea = new Rectangle(w, h);

  GTRenderer renderer = new StreamingRenderer();
  LabelCacheImpl labelCache = new LabelCacheImpl();
  Map<Object, Object> hints = renderer.getRendererHints();
  if (hints == null) {
    hints = new HashMap<>();
  }
  hints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache);
  renderer.setRendererHints(hints);
  renderer.setMapContent(mapContent);
  renderer.paint(g2d, outputArea, bounds);
  ImageIO.write(bufferedImage, "png", outputImageFile);
} catch (IOException ex) {
  ex.printStackTrace();
}

Ejecutar esto producirá una imagen como esta:

Si desea más color, necesita producir un Styleobjeto, ya sea leyendo un archivo SLD existente o usando StyleBuilderambos que se tratan en el manual del usuario .