3

I want to transform a geojson in a .png image. Do you have any lib/tool/tip to accomplish this task in Java? I googled a lot but no luck.

6
  • 1
    As a one off, or as part of a service?
    – nmtoken
    Commented Jun 29, 2017 at 17:39
  • 3
    gdal_rasterize will create a .png from almost any Vector format, including geojson. This isn't Java based.
    – klewis
    Commented Jun 29, 2017 at 19:09
  • @nmtoken as a maven dependency would be perfect.
    – Francesco
    Commented Jun 29, 2017 at 19:42
  • @klewis I will check for gdal I don't know it.
    – Francesco
    Commented Jun 29, 2017 at 19:42
  • geotools has everything you need
    – Ian Turton
    Commented Jun 29, 2017 at 19:46

2 Answers 2

7

If you chose GeoTools it is a fairly simple process, fetch your geojson from somewhere:

URL states = new URL("http://geojson.xyz/naturalearth-3.3.0/ne_110m_admin_1_states_provinces.geojson");
FeatureJSON featureJSON = new FeatureJSON();
FeatureCollection features = featureJSON.readFeatureCollection(states.openStream());

Then add them to a map with a style:

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

Finally create an image and render the map:

    File outputFile = new File("states.png");
    ImageOutputStream outputImageFile = null;
    FileOutputStream fileOutputStream = null;
    try {
      fileOutputStream = new FileOutputStream(outputFile);
      outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);
      int w = 1000;
      ReferencedEnvelope bounds = features.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();
    } finally {
      try {
        if (outputImageFile != null) {
          outputImageFile.flush();
          outputImageFile.close();
          fileOutputStream.flush();
          fileOutputStream.close();
        }
      } catch (IOException e) {// don't care now
      }
    }
  }
6
  • Hi, thanks for your solution. It works pretty well! How would you define the scale of the geojson file please?
    – hzitoun
    Commented May 13, 2020 at 15:30
  • 1
    GeoJSON is a vector format - it doesn't have a scale. To scale the map you can change the w variable which is the width of the map.
    – Ian Turton
    Commented May 13, 2020 at 16:25
  • could you please tell me if there is a way to get the GPS coordinates of a pixel in the outputted image? I want to georeference a sub-image in the big image and get the GPS coordinates. Many thanks in advance.
    – hzitoun
    Commented Apr 7, 2021 at 8:43
  • any help please? I just want to not loose the GPS coordinates when I generate the image. Is there a way to get a list of matches (x, y) in image <=> (lat, long) in geojson?
    – hzitoun
    Commented Jun 3, 2021 at 17:27
  • Hi Ian. What about the deprecation messages from FeatureJSON and readFeatureCollection() ? How can I update that?
    – Magno C
    Commented Aug 22 at 0:21
4

I read points from a shapefile and burn in a png, also with a color classification. The recipe is in python, you need in java but the structure is the same, only must to learn the image java api:

https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html

http://gdal.org/java/

import sys
from osgeo import gdal, ogr
from PIL import Image, ImageDraw

# Filename of input OGR file
vector_fn = 'points.shp'

# Open the data source and read in the extent
datasource = ogr.Open(vector_fn)

if datasource is None:
  print ('Could not open file')
  sys.exit(1)

vector_layer = datasource.GetLayer()


mapXmin, mapXmax, mapYmin, mapYmax = vector_layer.GetExtent()
# http://gdal.org/python/osgeo.ogr.Layer-class.html#GetExtent

print ("mapXmin:",mapXmin)
print ("mapXmax:",mapXmax)
print ("mapYmin:",mapYmin)
print ("mapYmax:",mapYmax)

print(mapXmin,mapYmin,mapXmax,mapYmax)

print ("W:",mapXmax-mapXmin)
print ("H:",mapYmax-mapYmin)

# Define pixel_size 
pixel_size = 0.5 # meters are one pixel
# Create the target data source
target_Width = int(abs(mapXmax - mapXmin) / pixel_size)
target_Height = int(abs(mapYmax - mapYmin) / pixel_size)


print ("target_Width:",target_Width)
print ("target_Height:",target_Height)


image = Image.new('RGBA', (target_Width, target_Height))
draw = ImageDraw.Draw(image)
r=6 #radio
# Loop through the features in the layer
feature = vector_layer.GetNextFeature()
while feature:

  # get the x,y coordinates for the point
  geom = feature.GetGeometryRef()

  xx = geom.GetX();yy = geom.GetY()
  x= int((xx-mapXmin) / pixel_size)
  y= int((mapYmax-yy) / pixel_size)

  value = feature.GetFieldAsDouble('valuation') 
  color = (18,173,42) #dark green
  if(value < 2500): color = (255,0,0) #red
  elif(value < 3000): color = (255,255,0) #yellow


  draw.ellipse((x-r, y-r, x+r, y+r), fill = color, outline =None)
  #draw.point((x, y), 'red')

  # destroy the feature and get a new one
  feature.Destroy()
  feature = vector_layer.GetNextFeature()

# close the data source and text file
datasource.Destroy()

image = image.resize((int(target_Width*0.5), int(target_Height*0.5)), Image.ANTIALIAS)
image.save('circles.png')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.