anon
anon

Reputation:

GeoDjango: How to create a circle anywhere on earth based on point and radius?

I have a similar question to this one. Using geodjango, I want to draw a circle on a map with a certain radius in km. However, the suggested solution

a) does not use km but instead degrees, and

b) becomes an oval further north or south.

Here is what I do:

from django.contrib.gis import geos
lat = 49.17
lng = -123.96
center = geos.Point(lng, lat)

radius = 0.01
circle = center.buffer(radius)

# And I then use folium to show a map on-screen:
map = folium.Map(
    location=[lat,lng],
    zoom_start=14,
    attr="Mapbox"
)
folium.GeoJson(
    circle.geojson,
    name="geojson",
).add_to(map)

The result is this:

Map with oval

How can I

a) draw a circle that is always 3 km in radius, independent from the position on the globe, and

b) ensure this is a circle and not an oval at all latitudes?

Upvotes: 1

Views: 916

Answers (2)

MarcelCode
MarcelCode

Reputation: 548

Here is the Code

from django.contrib.gis import geos
import folium

lat = 49.17
lng = -123.96
center = geos.Point(x=lng, y=lat, srid=4326)

center.transform(3857) # Transform Projection to Web Mercator     
radius = 3000 # now you can use meters
circle = center.buffer(radius) 
circle.transform(4326) # Transform back to WGS84 to create geojson

# And I then use folium to show a map on-screen:
map = folium.Map(
    location=[lat,lng],
    zoom_start=14,
    attr="Mapbox"
)
geojson = folium.GeoJson(
    circle.geojson,
    name="geojson",
)

geojson.add_to(map)

Explanation

This problem occurs due to Map Projections.

Lat/Long Coordinates are represented by the Map Projection WGS84. The Values are in degrees.

The map you see in folium has another map projection (Web Mercator). It tries to represent the world as a plane, which produces distortions to the north and south. The coordinate values are in meters.

On a globe your created circle would look completely round, but because folium uses another projection it gets distorted.

It is also important to know that every projection is represented by a number (EPSG Code). With this epsg codes, you can transform your coordinates from one projection into another.

  • Web Mercator -> EPSG 3857
  • WGS84 -> EPSG 4326

With my Code you now get a round circle in folium for Web Mercator, but be aware that it would look oval and distorted, when looking at it on a globe.

Circle on a map

This is just a very easy explanation. You might have a look at Map Projections to better understand the problem. This guide gives a good overview: Map Projections

Upvotes: 3

Progger
Progger

Reputation: 35

try this

folium.Circle(
radius=3000,
location=[lat,lng],
popup="Whatever name",
color="#3186cc",
fill=True,
fill_color="#3186cc",
).add_to(m)

Upvotes: 0

Related Questions