Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of Circle Geometry #206

Open
Kaveeshwar2k1 opened this issue May 15, 2024 · 2 comments
Open

Addition of Circle Geometry #206

Kaveeshwar2k1 opened this issue May 15, 2024 · 2 comments

Comments

@Kaveeshwar2k1
Copy link

Kaveeshwar2k1 commented May 15, 2024

I'm not sure whether it is already possible, but generating circular geometries with latitude and longitude as center with radius would be great in cases where a location's accuracy is used (as it always forms a circle).

As far as I've played with few libraries in hex.pm, only Geocalc had the option but it is only limited to three shapes.

I also tried to decode with WKT using CIRCULARSTRING, but it didn't help.

Geo.WKT.decode("CIRCULARSTRING(4 1, 7 4, 4 7, 1 4, 4 1)")

Result:

 %FunctionClauseError{
   module: Geo.WKT.Decoder,
   function: :do_decode,
   arity: 2,
   kind: nil,
   args: nil,
   clauses: nil
 }}
@s3cur3
Copy link
Contributor

s3cur3 commented Aug 30, 2024

Hi @Kaveeshwar2k1! I would very much like to add circle support. I'm a little unclear on the semantics of a CIRCULARSTRING, though. Is it providing two points which define the diameter of the circle? If so, I suppose it should just contain two points like this:

defmodule Geo.Circle do
  @moduledoc """
  Defines the Circle struct.
  """

  @type latitude :: number
  @type longitude :: number

  @type t :: %Geo.Circle{
          coordinates: [{longitude, latitude}, ...],
          srid: integer | nil,
          properties: map
        }
  defstruct coordinates: [{0, 0}, {0, 0}], srid: nil, properties: %{}
end

Does that sound right?

@simagyari
Copy link

Hi @s3cur3,
I am wonder if for the actual struct, a point and a radius would be a more precise representation. It does not assume point locations on the circumference and for encoding, decoding, and visualisation, the number of points that should be created on the circumference could be specified.

defmodule Geo.Circle do
  @moduledoc """
  Defines the Circle struct.
  """

  @type latitude :: number
  @type longitude :: number

  @type t :: %Geo.Circle{
          coordinates: {longitude, latitude},
          radius: integer | float,
          srid: integer | nil,
          properties: map
        }
  defstruct coordinates: {0, 0}, srid: nil, properties: %{}
end

For encoding to WKT or any other format, something like the following could be implemented:

defp do_encode(%Circle{coordinates: {longitude, latitude}, radius: radius}) do
  circumference_coordinates = for i <- 0..4 do
    angle = 2 * :math.pi() * i / 5
    lon = longitude + radius * :math.cos(angle)
    lat = latitude + radius * :math.sin(angle)
    {lon, lat}
  end

  coordinate_string = create_circular_string_str(circumference_coordinates)

  "CIRCULARSTRING#{coordinate_string}"

defp create_circular_string_str(coordinates) do
  coordinate_string =
    coordinates
    |> Enum.map(&create_coord_str(&1))
    |> Enum.join(",")

  "(#{coordinate_string})"

The number of circumference points to be created can of course be changed, I just randomly selected it here. It can potentially even be exposed to the user, though it should be no less than 5 points ideally, as we'd want multiple arc segments specified. I was also thinking about the first and last coordinate pair having to be the same, but I think it's not explicitly required, especially in this case, as it's just going to be recalculated back into a centre and a radius.

What do you think?

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

No branches or pull requests

3 participants