GeoJSON
“GeoJSON” is a standard for structuring JSON when encoding geometry and features. By using GeoJSON, rather than some other arbitrary scheme for structuring JSON, you maximize the interoperability of your JSON output. There are dozens of tools and websites that happily consume and emit GeoJSON.
The GeoJSON standard is formally maintained by the IETF as “RFC 7946”.
Unlike WKB and WKT, GeoJSON does not restrict itself to just geometry representation. It also standardizes the transport of attribution. The three key levels of GeoJSON are:
- Geometry, representation of Points, LineStrings, Polygons, etc.
- Feature, representation of an object that has a “geometry” and an arbitrary set of other non-geometric “properties”.
- FeatureCollection, representation of a list of Features.
Since GEOS is almost 100% concerned with geometry operations, there is no GEOS abstraction to translate the non-geometric properties of GeoJSON Feature into, so handling of Feature properties is only available via the C++ GeoJSON.h utilities.
The GeoJSON writer, in both the C and C++ APIs, only supports writing out the Geometry portion of GeoJSON. So for writing features, the writer will end up embedded in some larger JSON emitter.
/* Read a linestring */
const char* linestring = "LINESTRING(0 0 1, 1 1 1, 2 1 2)";
GEOSWKTReader* reader = GEOSWKTReader_create();
GEOSGeom* geom = GEOSWKTReader_read(reader, linestring);
/* Write it out as GeoJSON */
GEOSGeoJSONWriter* writer = GEOSGeoJSONWriter_create();
/* Generate the JSON, with an indentation of 2 */
int indentation = 2;
unsigned char* json = GEOSGeoJSONWriter_writeGeometry(writer, geom, indentation);
/* do something ... */
/* Free the WKB */
GEOSFree(json);
GEOSGeom_destroy(geom);
GEOSGeoJSONWriter_destroy(writer);
GEOSWKTReader_destroy(reader);
The C++ GeoJSON reader does include the option to read full Feature
and FeatureCollection
objects, with a narrow API for reading the resulting objects.
#include <geos/io/GeoJSON.h> // GeoJSONFeatureCollection, etc
#include <geos/io/GeoJSONReader.h>
#include <geos/io/WKTWriter.h>
#include <geos/geom/Geometry.h>
using namespace geos::io;
using namespace geos::geom;
void main(void)
{
// Read file into string
std::ifstream ifs("geojson.json");
std::string content((std::istreambuf_iterator<char>(ifs) ),
(std::istreambuf_iterator<char>() ));
// Parse GeoJSON string into GeoJSON objects
GeoJSONReader reader;
GeoJSONFeatureCollection fc = reader.readFeatures(content);
// Prepare WKT writer
WKTWriter writer;
writer.setTrim(true); // Only needed before GEOS 3.12
writer.setRoundingPrecision(2);
// Print out the features
for (auto& feature: fc) {
// Read the geometry
const Geometry* geom = feature.getGeometry();
// Read the properties
std::map<std::string, GeoJSONValue>& props = feature.getProperties();
// Write all properties
std::cout << "----------" << std::endl;
for (const auto& prop : props) {
std::cout << prop.first << ": " << prop.second << std::endl;
}
// Write WKT feometry
std::cout << "geometry: " << writer.write(geom) << std::endl;
}
}