All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.locationtech.spatial4j.io.GeoJSONWriter Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2015 VoyagerSearch
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License, Version 2.0 which
 * accompanies this distribution and is available at
 *    http://www.apache.org/licenses/LICENSE-2.0.txt
 ******************************************************************************/

package org.locationtech.spatial4j.io;

import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.context.SpatialContextFactory;
import org.locationtech.spatial4j.distance.DistanceUtils;
import org.locationtech.spatial4j.shape.*;
import org.locationtech.spatial4j.shape.impl.BufferedLine;
import org.locationtech.spatial4j.shape.impl.BufferedLineString;
import org.locationtech.spatial4j.shape.impl.GeoCircle;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.text.NumberFormat;
import java.util.Iterator;

import static org.locationtech.spatial4j.io.GeoJSONReader.BUFFER;
import static org.locationtech.spatial4j.io.GeoJSONReader.BUFFER_UNITS;

public class GeoJSONWriter implements ShapeWriter {

  public GeoJSONWriter(SpatialContext ctx, SpatialContextFactory factory) {

  }

  @Override
  public String getFormatName() {
    return ShapeIO.GeoJSON;
  }

  protected void write(Writer output, NumberFormat nf, double... coords) throws IOException {
    output.write('[');
    for (int i = 0; i < coords.length; i++) {
      if (i > 0) {
        output.append(',');
      }
      output.append(nf.format(coords[i]));
    }
    output.write(']');
  }

  @Override
  public void write(Writer output, Shape shape) throws IOException {
    if (shape == null) {
      throw new NullPointerException("Shape can not be null");
    }
    NumberFormat nf = LegacyShapeWriter.makeNumberFormat(6);
    if (shape instanceof Point) {
      Point v = (Point) shape;
      output.append("{\"type\":\"Point\",\"coordinates\":");
      write(output, nf, v.getX(), v.getY());
      output.append('}');
      return;
    }
    if (shape instanceof Rectangle) {
      Rectangle v = (Rectangle) shape;
      output.append("{\"type\":\"Polygon\",\"coordinates\":[[");
      write(output, nf, v.getMinX(), v.getMinY());
      output.append(',');
      write(output, nf, v.getMinX(), v.getMaxY());
      output.append(',');
      write(output, nf, v.getMaxX(), v.getMaxY());
      output.append(',');
      write(output, nf, v.getMaxX(), v.getMinY());
      output.append(',');
      write(output, nf, v.getMinX(), v.getMinY());
      output.append("]]}");
      return;
    }
    if (shape instanceof BufferedLine) {
      BufferedLine v = (BufferedLine) shape;
      output.append("{\"type\":\"LineString\",\"coordinates\":[");
      write(output, nf, v.getA().getX(), v.getA().getY());
      output.append(',');
      write(output, nf, v.getB().getX(), v.getB().getY());
      output.append(',');
      output.append("]");
      if (v.getBuf() > 0) {
        output.append(',');
        output.append("\"buffer\":");
        output.append(nf.format(v.getBuf()));
      }
      output.append('}');
      return;
    }
    if (shape instanceof BufferedLineString) {
      BufferedLineString v = (BufferedLineString) shape;
      output.append("{\"type\":\"LineString\",\"coordinates\":[");
      BufferedLine last = null;
      Iterator iter = v.getSegments().iterator();
      while (iter.hasNext()) {
        BufferedLine seg = iter.next();
        if (last != null) {
          output.append(',');
        }
        write(output, nf, seg.getA().getX(), seg.getA().getY());
        last = seg;
      }
      if (last != null) {
        output.append(',');
        write(output, nf, last.getB().getX(), last.getB().getY());
      }
      output.append("]");
      if (v.getBuf() > 0) {
        writeDistance(output, nf, v.getBuf(), shape.getContext().isGeo(), BUFFER, BUFFER_UNITS);
      }
      output.append('}');
      return;
    }
    if (shape instanceof Circle) {
      // See: https://github.com/geojson/geojson-spec/wiki/Proposal---Circles-and-Ellipses-Geoms
      Circle v = (Circle) shape;
      Point center = v.getCenter();
      output.append("{\"type\":\"Circle\",\"coordinates\":");
      write(output, nf, center.getX(), center.getY());
      writeDistance(output, nf, v.getRadius(), v instanceof GeoCircle, "radius", "radius_units");
      output.append("}");
      return;
    }
    if (shape instanceof ShapeCollection) {
      ShapeCollection v = (ShapeCollection) shape;
      output.append("{\"type\":\"GeometryCollection\",\"geometries\":[");
      for (int i = 0; i < v.size(); i++) {
        if (i > 0) {
          output.append(',');
        }
        write(output, v.get(i));
      }
      output.append("]}");
      return;
    }
    output.append("{\"type\":\"Unknown\",\"wkt\":\"");
    output.append(LegacyShapeWriter.writeShape(shape));
    output.append("\"}");
  }

  /**
   * Helper method to encode a distance property (with optional unit). 
   * 

* The distance unit is only encoded when isGeo is true, and it is converted to km. *

*

* The distance unit is encoded within a properties object. *

* @param output The writer. * @param nf The number format. * @param dist The distance value to encode. * @param isGeo The flag determining * @param distProperty The distance property name. * @param distUnitsProperty The distance unit property name. */ void writeDistance(Writer output, NumberFormat nf, double dist, boolean isGeo, String distProperty, String distUnitsProperty) throws IOException { output.append(",\"").append(distProperty).append("\":"); if (isGeo) { double distKm = DistanceUtils.degrees2Dist(dist, DistanceUtils.EARTH_MEAN_RADIUS_KM); output.append(nf.format(distKm)); output.append(",\"properties\":{"); output.append("\"").append(distUnitsProperty).append("\":\"km\"}"); } else { output.append(nf.format(dist)); } } @Override public String toString(Shape shape) { try { StringWriter buffer = new StringWriter(); write(buffer, shape); return buffer.toString(); } catch (IOException ex) { throw new RuntimeException(ex); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy