diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8be02da7e..da00eaec2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,6 +32,7 @@ variables: APP_VERSION: "${CI_COMMIT_REF_NAME}" APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz" CYPRESS_INSTALL_BINARY: 0 + HEX_MIRROR: https://cdn.jsdelivr.net/hex cache: key: "${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}" diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index 6d4b1a50f..6f0887f94 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -1330,12 +1330,15 @@ defmodule Mobilizon.Events do defp events_for_location(query, %{location: location, radius: radius}) when is_valid_string(location) and not is_nil(radius) do with {lon, lat} <- Geohax.decode(location), - point <- Geo.WKT.decode!("SRID=4326;POINT(#{lon} #{lat})") do + point <- Geo.WKT.decode!("SRID=4326;POINT(#{lon} #{lat})"), + {{x_min, y_min}, {x_max, y_max}} <- search_box({lon, lat}, radius) do query |> join(:inner, [q], a in Address, on: a.id == q.physical_address_id, as: :address) |> where( - [q], - st_dwithin_in_meters(^point, as(:address).geom, ^(radius * 1000)) + [q, ..., a], + st_x(a.geom) > ^x_min and st_x(a.geom) < ^x_max and + st_y(a.geom) > ^y_min and st_y(a.geom) < ^y_max and + st_dwithin_in_meters(^point, a.geom, ^(radius * 1000)) ) else _ -> query @@ -1344,6 +1347,15 @@ defmodule Mobilizon.Events do defp events_for_location(query, _args), do: query + @spec search_box({float(), float()}, float()) :: {{float, float}, {float, float}} + defp search_box({lon0, lat0}, radius) do + km_per_lat_deg = 111.195 + lat_amp = radius / km_per_lat_deg + km_per_lon_deg_at_lat = Haversine.distance({0.0, lat0}, {1.0, lat0}) / 1000 + lon_amp = radius / km_per_lon_deg_at_lat + {{lon0 - lon_amp, lat0 - lat_amp}, {lon0 + lon_amp, lat0 + lat_amp}} + end + @spec filter_online(Ecto.Query.t(), map()) :: Ecto.Query.t() defp filter_online(query, %{type: :online}), do: is_online_fragment(query, true) diff --git a/mix.exs b/mix.exs index 7fd786b06..7281283a5 100644 --- a/mix.exs +++ b/mix.exs @@ -218,7 +218,8 @@ defmodule Mobilizon.Mixfile do {:mox, "~> 1.0", only: :test}, {:junit_formatter, "~> 3.1", only: [:test]}, {:sobelow, "~> 0.8", only: [:dev, :test]}, - {:doctor, "~> 0.18.0", only: :dev} + {:doctor, "~> 0.18.0", only: :dev}, + {:haversine, "~> 0.1.0"} ] ++ oauth_deps() end diff --git a/mix.lock b/mix.lock index 236ef569a..7a6c6c97e 100644 --- a/mix.lock +++ b/mix.lock @@ -64,6 +64,7 @@ "guardian_db": {:hex, :guardian_db, "2.1.0", "ec95a9d99cdd1e550555d09a7bb4a340d8887aad0697f594590c2fd74be02426", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.1", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:guardian, "~> 1.0 or ~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "f8e7d543ac92c395f3a7fd5acbe6829faeade57d688f7562e2f0fca8f94a0d70"}, "guardian_phoenix": {:hex, :guardian_phoenix, "2.0.1", "89a817265af09a6ddf7cb1e77f17ffca90cea2db10ff888375ef34502b2731b1", [:mix], [{:guardian, "~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "21f439246715192b231f228680465d1ed5fbdf01555a4a3b17165532f5f9a08c"}, "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, + "haversine": {:hex, :haversine, "0.1.0", "14240e90dae07c9459f538d12a811492f655d95fc68f999403503b4f6c4ec522", [:mix], [], "hexpm", "54dc48e895bc18a59437a37026c873634e17b648a64cb87bfafb96f64d607060"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, "http_signatures": {:hex, :http_signatures, "0.1.1", "ca7ebc1b61542b163644c8c3b1f0e0f41037d35f2395940d3c6c7deceab41fd8", [:mix], [], "hexpm", "cc3b8a007322cc7b624c0c15eec49ee58ac977254ff529a3c482f681465942a3"}, "httpoison": {:hex, :httpoison, "1.8.1", "df030d96de89dad2e9983f92b0c506a642d4b1f4a819c96ff77d12796189c63e", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "35156a6d678d6d516b9229e208942c405cf21232edd632327ecfaf4fd03e79e0"}, diff --git a/priv/repo/migrations/20220407083712_add_indexes_to_addresses.exs b/priv/repo/migrations/20220407083712_add_indexes_to_addresses.exs new file mode 100644 index 000000000..9ba7dd112 --- /dev/null +++ b/priv/repo/migrations/20220407083712_add_indexes_to_addresses.exs @@ -0,0 +1,13 @@ +defmodule Mobilizon.Storage.Repo.Migrations.AddIndexesToAddresses do + use Ecto.Migration + + def up do + create_if_not_exists(index("addresses", ["st_x(geom)"], name: "idx_addresses_geom_x")) + create_if_not_exists(index("addresses", ["st_y(geom)"], name: "idx_addresses_geom_y")) + end + + def down do + drop_if_exists(index("addresses", ["st_x(geom)"], name: "idx_addresses_geom_x")) + drop_if_exists(index("addresses", ["st_y(geom)"], name: "idx_addresses_geom_y")) + end +end