Skip to content

Instantly share code, notes, and snippets.

@tmcw
Last active July 18, 2022 15:14
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmcw/037a1cb6660d74a392e9da7446540f46 to your computer and use it in GitHub Desktop.
Save tmcw/037a1cb6660d74a392e9da7446540f46 to your computer and use it in GitHub Desktop.

Bonus geometry types in GeoJSON

Basically two types:

  1. Rectangles
  2. Circles

Let's say you have a drawing tool that permits both. Both geometry types benefit from some non-standard drawing abilities: it would be nice to resize circles, and it would be nice to resize rectangles in a way that keeps them rectangular. However, GeoJSON does not have circle or rectangle types. Both are represented as polygons. This gives us two options:

  1. "Detect" these shapes with a heuristic. This is doable for a rectangle by checking the corners, but much, much less doable for circles. Also, circles have an additional property that I will mention in the next bit.
  2. "Explicitly mark" these shapes with a property. This would be something like this in a the Feature's properties object:
{
  "@type": "circle"
}

Then, if you do an editing action that makes the thing not a circle, like deleting or moving an individual attribute, you remove that property, which then removes all the special-behavior stuff.

Circles, cont.

Another thing about circles, and probably the reason why almost no formats want to mess with them, except GML, which is cursed, is that it's really hard to say what a circle is. Is it a geodesic circle that looks weird in mercator? A mercator circle that looks weird in equirectangular? How many points?

The other thing with circles could be like (in the Feature's properties object)

{
  "@type": "circle/geodesic"
}

To specify the kind. Additionally, you could, say, store the "radius" of the circle in there. But I think that's something that can be somewhat reliably derived from the shape? Right?

Just to make it explicit

Circles and Rectangles in this vision are still just GeoJSON Polygons. So a Circle is a Polygon that's circular-shaped, with the individual nodes. This isn't proposing adding a circle type or a rectangle type. It's about indicating which polygons are special.

Also, by using the properties object, this:

  • Avoids being weird with the spec and adding a new key somewhere that is unexpected
  • But also will show that new property in various "editing interfaces" like Placemark

I, personally, like the idea of using properties rather than extending different little bits of GeoJSON, like adding a key in Geometry, because it's much less likely that the data will be lost by some GeoJSON conversion tool that ignores unknown properties. However, this does mean that only Features can be circles or rectangles, not bare Geometries.


Anyway, I would love to either:

  • Establish a shared convention so that Placemark-drawn features work elsewhere and vice versa
  • Or find an existing convention so that a new standard is not invented
@rowanwins
Copy link

Thanks for writing up these notes @tmcw

The way I'm doing this ATM within an app is that I have a ES6 class for each geometry type, so when a user draws any shape it creates an instance of the class. For most standard geometry types the class doesn't do much, but for non-standard types like circle and rectangle it can hold whatever required bits for editing like circle centroid or radius, rectangle rotation etc.
The class then exposes a method or getter for getting the geometry as plain geojson (which I use a standard polygon representation for circles and rectangles).

What I haven't quite sorted out is what to do when someone provides pre-existing circles or rectangles which is the crux of this gist!

  • I like the idea of a @type property, although maybe @geometry-type is slightly more explicit, but that's a very minor quibble.
  • I agree with utilising the properties object even with it's limitations of only belonging on a feature.
  • rectangle strikes me as the slightly trickier to share and reuse mainly due to rotation, so whether we need a secondary property to denote that I'm not sure, although perhaps it can be calculated easily enough.

Anyway working towards a standard-ish way of doing things would be great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment