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

org.dstadler.ctw.geojson.GeoJSON Maven / Gradle / Ivy

package org.dstadler.ctw.geojson;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import org.dstadler.ctw.utils.LatLonRectangle;

import com.github.filosganga.geogson.gson.GeometryAdapterFactory;
import com.github.filosganga.geogson.gson.PositionsAdapter;
import com.github.filosganga.geogson.model.Feature;
import com.github.filosganga.geogson.model.FeatureCollection;
import com.github.filosganga.geogson.model.LinearRing;
import com.github.filosganga.geogson.model.Point;
import com.github.filosganga.geogson.model.Polygon;
import com.github.filosganga.geogson.model.positions.Positions;
import com.github.filosganga.geogson.model.positions.SinglePosition;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonWriter;

/**
 * Utility class to provide some functionality
 * for creating GeoJSON files
 */
public class GeoJSON {
	private static final Gson gson = new GsonBuilder()
			.registerTypeAdapterFactory(new GeometryAdapterFactory())
			// override the adapter for Positions to write only with 5 decimal
			// places to optimize size of geo-json files
			// this should still give precision down to single meters
			.registerTypeAdapter(Positions.class, new PositionsAdapter() {
				@Override
				public void write(JsonWriter out, Positions value) throws IOException {
					if (value == null) {
						out.nullValue();
					} else {
						out.beginArray();
						if (value instanceof SinglePosition) {
							SinglePosition sp = (SinglePosition) value;
							out.value(formatDecimal(sp.lon()));
							out.value(formatDecimal(sp.lat()));
							if (!Double.isNaN(sp.alt())) {
								out.value(formatDecimal(sp.alt()));
							}
						} else {
							for (Positions child : value.children()) {
								write(out, child);
							}
						}
						out.endArray();
					}
				}
			})
			.create();

	protected static double formatDecimal(double d) {
		// use only 5 decimal digits to reduce the size of the geo-json
		return BigDecimal.valueOf(d).setScale(5, RoundingMode.HALF_UP).doubleValue();
	}

	public static Feature createSquare(LatLonRectangle rec, String property) {
		Feature.Builder builder = Feature.builder().withGeometry(Polygon.of(LinearRing.of(
				Point.from(rec.lon1, rec.lat1),
				Point.from(rec.lon2, rec.lat1),
				Point.from(rec.lon2, rec.lat2),
				Point.from(rec.lon1, rec.lat2),
				Point.from(rec.lon1, rec.lat1)
		)));

		if (property != null) {
			builder.withProperty("popupContent", new JsonPrimitive(property));
		}

		return builder.build();
	}

	public static Feature createLines(LatLonRectangle rec, String property) {
		Feature.Builder builder = Feature.builder().withGeometry(LinearRing.of(
				Point.from(rec.lon1, rec.lat1),
				Point.from(rec.lon2, rec.lat1),
				Point.from(rec.lon2, rec.lat2),
				Point.from(rec.lon1, rec.lat2),
				Point.from(rec.lon1, rec.lat1)
		));

		if (property != null) {
			builder.withProperty("popupContent", new JsonPrimitive(property));
		}

		return builder.build();
	}

	public static void writeGeoJSON(String jsonOutputFile, String varPrefix, List features) throws
			IOException {
		FeatureCollection collection = new FeatureCollection(features);
		try (Writer writer = new BufferedWriter(new FileWriter(jsonOutputFile))) {
			writer.write("var " + varPrefix + "states=[");
			gson.toJson(collection, writer);
			writer.write("];");
		}
	}

	public static InputStream getGeoJSON(List features) throws IOException {
		FeatureCollection collection = new FeatureCollection(features);
		try (ByteArrayOutputStream stream = new ByteArrayOutputStream();
			Writer writer = new BufferedWriter(new OutputStreamWriter(stream))) {
			gson.toJson(collection, writer);

			writer.flush();
			stream.flush();

			return new ByteArrayInputStream(stream.toByteArray());
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy