22

When I look up the specs of GeoJson I see that circles are supported:

http://geopriv.dreamhosters.com/geojson/geojson-spec.html#circleExample

When I try out the code in geojsonlint (http://geojsonlint.com/) however, it gives me an error.

Input:

{ 
"type": "Circle",
"coordinates": [4.884, 52.353],
"radius": 200
}

Gives:

"Circle" is not a valid GeoJSON type. 

I want to show different places of interests with a range of influence on a map by using d3. It needs GeoJson for input but it is true that circles are not supported with GeoJson?

cantdutchthis
  • 31,949
  • 17
  • 74
  • 114
  • You caould override `L.Circle.toGeoJSON()` to add additional properties to indicate that the Point should be represented as a circle: https://github.com/Leaflet/Leaflet/issues/2888 Although it isn't standard, it gives you the metadata to know to represent as a circle. – Mads Hansen Jan 07 '15 at 20:59
  • Ah yes, but that will be solved by using the Leaflet api. This would work but you would not be using geojson per se, you would be using the functionality that leaflet gives you. D3 would offer a similar solution that is independent of the mapping library that you use. – cantdutchthis Jan 08 '15 at 09:44

4 Answers4

37

When I look up the specs of GeoJson I see that circles are supported

They aren't. Seems you managed to find some fake or incorrect specs. Go to geojson.org to find the specs, there's nothing about circles.

Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
L. Sanna
  • 6,482
  • 7
  • 33
  • 47
  • 1
    I think he found something in draft or propositions like here https://github.com/geojson/geojson-spec/issues/1 or https://github.com/geojson/geojson-spec/wiki/Proposal---Circles-and-Ellipses-Geoms – Mika Andrianarijaona Jul 20 '16 at 13:32
24

As the accepted answer explains, circles are not supported in the GeoJson spec.

Most map implementations will, however, let you create circles, but in case this doesn't work for you (eg. you need to store it in a database and query it), the solution is to create a polygon that roughly approximates a circle (imagine a polygon with 32+ edges).

I wrote a module that does this. You can use it like this:

const circleToPolygon = require('circle-to-polygon');

const coordinates = [-27.4575887, -58.99029]; //[lon, lat]
const radius = 100;                           // in meters
const numberOfEdges = 32;                     //optional that defaults to 32

let polygon = circleToPolygon(coordinates, radius, numberOfEdges);

To clarify why circles are not supported, it has to do with the curvature of the earth. Because the earth is not a perfect sphere, if you were to draw a circular shape on it, it wouldn't be a perfect circle either. However, the solution above works for most scenarios in which you don't require critical precision.

arg20
  • 4,893
  • 1
  • 50
  • 74
10

No circle support from geojson, but you can use LineString to simulate a circle

use a LineString geiometry object

"geometry": {
        "type": "LineString",
        "coordinates": [
                    [center_X, center_y],
                    [center_X, center_y]
                ]
      }

then set the dynamic style use radius as the strokeweight

function featureStyle(feature){
    return {
      strokeWeight: radius,
    };
  }

it looks like a circle on the map.

smac89
  • 39,374
  • 15
  • 132
  • 179
Chen Yuling
  • 101
  • 1
  • 3
-1
A circle... some code I use for making a circle for an OpenStreetMap

-- x is decimal latitude
-- y is decimal longitude
-- r is radius --  .00010 is about 40m in OSM (3 about 50km)

-- Adjust for map latitude distortion further north or south

x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)

-- For loop to gather all the points of circle here 1 to 360
-- can also use the for loop to make some other interesting shapes

for i = 1, 360 do
    angle = i * math.pi / 180
    ptx = x + r * math.cos( angle )
    pty = y + r * math.sin( angle )

-- readjust latitude for map distortion

    ptx = 180/math.pi * (2 * math.atan(math.exp( ptx * math.pi/180)) - math.pi/2 )

-- Build an array of positions for GeoJSON - formatted lat and long

    data[i] = '[' .. string.format("%.6f",pty) .. ","
    data[i] = data[i] .. string.format("%.6f",ptx) .. ']'

-- End of for loop
end

-- Cycle through the data array with another for loop to build the
   coordinates (put in brackets and commas etc. for the actual
   GeoJSON coordinates string. Add data[1] to the end to close
   the polygon (circle). A circle.

-- If you want a solid circle then use fill and a hex color
-- If you want a LineString just make fill invisible or #ffffff
      Include the stroke-width and stroke-color parameters as well.
-- If latitude is greater than 89.5 or less than -89.5 you may wish
   to cut off the circle by drawing a line at polar regions by using
   those latitudes.
-- I use this simply for several circles and not for hundreds of them.

Cheers!
-- 
Matroc
  • 19