За сколько времени вы смогли бы написать и закодить такой алгоритм?

Коллеги, добрый день. У нас тут вышла дискуссия об эстимейтах, поэтому, в рамках спортивного интереса, хотелось бы услышать мнение коллективного разума.

API Google Places умеет искать места в радиусе до 50 км. Чтобы найти места на территории большего радиуса, необходимо разбить её на несколько участков и сделать несколько запросов. Их должно быть минимально возможное количество, при этом территория должна быть покрыта полностью, но с как можно меньшей погрешностью. Также должна учитываться кривизна земной поверхности.

На вход функции поступают координаты центра и требуемого радиуса. На выходе должен быть возвращён массив кортежей вида (lat, lng, r), где lat, lng — координаты центра подокружности радиусом менее 10 км, для которой будет выполнен подзапрос, и r — её радиус.

Вопрос 1. За какое время, в часах, вы сможете составить и закодить на комфортном для вас языке программирования вышеописанный алгоритм?

Вопрос 2. За какое время, как вы считаете, эту же задачу может выполнить разработчик в Google? (Полагая, что он не пользуется служебным положением для изменения API.)

Спасибо. :)

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

хтось в курсі, аутентифікація у них тільки по токену, чи вони ще просять ip вашого сервера під’єднати?
А то ту такі ціни jumpshare.com/v/ufcVdOgz4Flu3AhWn5VJ
на автокомліт менше 3$ за 1000 запитів
Якщо прийдеться використовувати буду через проксі стукати))
Не то що я жлоб, любий проект не зразу приносить прибутки, вони з розціками щось погнали))

Оо, прикольна задача. Ну вставлю і я свої 5 копійок.
* ця задача в точності відповідає задачі Томпсона з фізики, розв’язується таке лише чисельним моделюванням. З іншого боку, якщо один раз змоделити і зберегти отримані координати, то можна ними послуговуватись, доки радіус Землі не зміниться :)
* якщо питання хоч що-небудь робоче зліпити, то одразу приходить думка розбивати на шестикутники, бо радіус запиту значно менший радіусу Землі і на таких масштабах кривина майже не помітна, а значить шестикутники (найоптимальніше рішення для площини) не може бути аж дуже поганим. Генерувати їх можна починаючи з полюса сфери і далі «поясками». В кожному пояску буде приблизно 6*n шестикутників, а зміщення між ними по куту тета sqrt(3)*r/R (кутова відстань між центрами сусідніх шестикутників в радіанах). Далі можна накастувати поворот, щоб центральний шестикутник опинився на потрібних координатах і все. Буде трохи зайвих перекриттів, особливо для великих радіусів запиту, але я не думаю, що то так смертельно: для радіусу розміром з півпланети для запитів біля екватора середня відстань між центрами від оптимальної в приблизно 1.7*r впаде до 1.15*r (якщо не напутав в оцінках). Як би це могло виглядати прикинув нижче:

DISCLAIMER: всіх чутливих до якості коду прохання не читати, або запастись відром — зговнякано на як-попало в 3-й ночі, аби лише запускалось і хтось міг потрейсити. Можуть бути баги, невраховані кейси чи навіть визиватись ктулху.

from math import *

def adjust(phi, theta, p_phi, p_theta): # theta than phi
    return [\
    atan2(sin(theta)*sin(phi), cos(theta)*sin(p_theta) + cos(p_theta)*cos(phi)*sin(theta)) + p_phi, \
    acos(cos(p_theta)*cos(theta) - cos(phi)*sin(p_theta)*sin(theta))]

def get_points(lat, lng, given_r, r=10.0, R=6371.0):
    phi, theta = (lng/180.0*pi, (lat+90.0)/180.0*pi) # latitude theta;  longitude  phi
    iters   = 1 + (int(given_r / r) if given_r <= 4.0 * r else 1+int(ceil(given_r / (sqrt(3) * r))))
    indices = sum([[[n,k] for k in xrange(0, 6*n)] for n in xrange(1, iters)],[])
    points  = [[0.0, 0.0]] + map(lambda x: [(x[1] + 0.5*(x[0] % 2))*pi/3.0/x[0], x[0]*sqrt(3)*r/R], indices)
    coords  = map(lambda p: adjust(p[0], p[1], phi, theta), points)
    geo_c   = map(lambda p: [p[1]/pi*180.0-90.0, p[0]/pi*180.0], coords)
    return geo_c

print get_points(30.0, 70.0, 100.0)
заюзать уже готовые формулы для эллипсоидов, или даже просто код, что в опенсурсе пачками валяется

Тоді уже й повністю готове рішення можна забрати — впевнений, що у відкритому доступі є не те що код, а навіть готове достатньо дрібне розбиття поверхні Землі, лише в файл зберегти й користуватись потім. Але я ж так розумію, що челедж був самому щось якнайшвидше згавнокодити.

для эллипсоидов

та і так точність плюс-мінус лопата, не думаю, що врахування такого щось дасть. Середній радіус Землі 6371.0 km, а на екваторіальний та «полюсний» складають 6378.1 km та 6356.8 km відповідно. Це 0.2% похибки, тобто глобус радіусом метр (в двері вже не влізе) буде відхилятись від ідеальної сферичної форми всього на 2 мм.

баги в таких делах самое долгое. так что месяц только на баги и edge cases

Раз на входе окружность и искать можно только окружностями, то ясно что это гексовая сетка. На одной крайности у нас один круг, на другой — «круг» составленный из меньших кругов (расположенных на гексовой сетке). Можно ещё подтюнить размер этих кругов, если имеет смысл. 1ч первый работающий в-т, 1 день — с оптимизациями, тестами и кофе-брейками.

Если честно, то я бы не городил огород и полученные координаты обрезал бы до bounding box задаными четырьмя парами lat, lng. Таким образом локально будет хранится сетка квадратов. Да, количество запросов будет несколко больше, чем если оперировать кругами или шестиугольниками, но далеко не факт, если потому нужно будет дозапрашивать маленькие перекрывающие кусочки. С использованием bounding box не нужно заморачиваться кривизной поверхности земли.

Это действительно было бы намного проще, но именно это API гугла (places nearby search) не поддерживает квадраты.

Правильно, запрашивать окружность с радиусом равным половины диагонали квадрата. И потом по приехавшему сету пройтись и повыкидывать все координаты за пределами нашего локального квадрата.

именно так и делал

Говоря «квадрат», учтите, что градус широты по длине равен градусу долготы только на экваторе. Поэтому чтобы получить квадрат не забудьте умножить на косинус широты )

Просто есть сильное подозрение, что у них данные внутри всё равно хранятся квадратами, только в API радиус, поэтому надо быть осторожным с локациями на самой окружности, их гугл может просто по-обрезать из-за округления. И оперировать только квадратами, вписанными в эту окружность (то, что я предлагал выше).

а внутри какой-нибудь геохэш прямоугольный)

Пока жители Виллабаджо зубрят геометрию, жители Вилларибо прочитали документацию и уже пишут код

так, але там прікол з Required parameters, текст обовязковий

Ты хоть раз пробовал смотреть на землю со стороны? :) Это летающая сморщенная картошка, никакой не эллипсоид и не геоид, так что те формулы — это сплошная аппроксимация для выпуклового тела и в низинах они будут давать охренительные погрешности при расчётах. Есть шанс, что гугл это всё учитывает у себя, нужно просто отсекать граничные координаты из полученного списка.

В общем посылаю тебя читать про эту тему и не придумывать про сморщенные картошки.

Специально для тебя: www.sciencealert.com/...​-actually-lumpy-not-round — обычный бесформенный астероид с налипшей биомассой.

Ви не праві. Радіус Землі близько 6000 км, висота найвищих гір 8 км, глибина Маріанської впадини 11 км, чи щось таке. Якщо Ви зробите модель планети радіусом 1 метр, то що гори, що впадини, не перевищать 2 мм, а Ви подивіться на цю модель, тут же деформації просто кінські. Якщо проглянути статтю, на яку Ви посилаєтесь, то там чітко написано, що то не справжня форма, а результати гравітаційних вимірювань. Деталей нема, але дозволю собі зробити припущення, як її отримано: міряється гравітаційне поле в кожній точці, а потім будується така модель, що матиме той самий розподіл при _рівномірній_густині_. Як приклад: я візьму кулю, половина якої з заліза, а половина з дерева. Частини я піджену одна до одної ідеально. Тепер поміряю їх гравітаційний вплив і виявлю, що залізна половина тягне сильніше. А тепер якщо відбудувати модель тіла в допущенні рівномірної густини (якби вона була з якогось деревозаліза), то залізна половина дико розпухне, бо їй треба тягнути куди сильніше ніж дерев’яній.

Так я не про помилку обчислень, а про те, що наша планета дуже слабо відрізняється від сферичної — всі ці випуклості-ввігнутості мають порядок десятих долей процента середнього радіуса. Якщо вся модель влазить на монітор, то таких незначних відхилень не повинно бути помітно (вони менше 1 пікселя будуть). А те що там на картинці так здеформовано що здеформовано і очевидно не відповідає справжній формі Землі.

а про те, що наша планета дуже слабо відрізняється від сферичної

NASA утверждает, что земля — это вообще груша %) www.youtube.com/watch?v=nTOE4Ar0Dfo

То-то я думаю всі кажуть, що Земля довкола якоїсь осі крутиться, а то ж черенок від груші... :)

Кстати, забавный факт, что NASA не опубликовало ни единой нормальной фотки земли — всё, что есть — это продукт художников.

Так правильно, а я ж хіба не так написав?

там чітко написано, що то не справжня форма, а результати гравітаційних вимірювань. Деталей нема, але дозволю собі зробити припущення, як її отримано: міряється гравітаційне поле в кожній точці, а потім будується така модель, що матиме той самий розподіл при _рівномірній_густині_. Як приклад: я візьму кулю, половина якої з заліза, а половина з дерева. Частини я піджену одна до одної ідеально. Тепер поміряю їх гравітаційний вплив і виявлю, що залізна половина тягне сильніше. А тепер якщо відбудувати модель тіла в допущенні рівномірної густини (якби вона була з якогось деревозаліза), то залізна половина дико розпухне, бо їй треба тягнути куди сильніше ніж дерев’яній.

Я не знаю масштаб тех гравитационных отклонений, как на картинке, но в теории вода должна прекрасно реагировать на такую гравитационную разницу, принимая форму гравитационного поля.

в теории вода должна прекрасно реагировать на такую гравитационную разницу

Ваша правда, повинна.

принимая форму гравитационного поля

Не зовсім так. Її задача не прийняти чиюсь форму, а мінімізувати потенціальну енергію системи, а то вже трохи різні речі. Тому рівень океану може там-сям трохи відрізнятися, в тому числі за рахунок нерівномірного гравітаційного поля, але на Еверест вода з океану не полізе, хоча там купа каменюк і вони притягують.

Знайшов прикольне посилання
www.scienceinthenews.org.uk/contents/?article=25
Там на початку є список міст і значення g для них, а ще далі є картинка, майже така як Ви приводили, і до неї текст:

The picture shows high gravity areas as red and low gravity areas as blue. The shape of the Earth has been vastly exaggerated to show the effect on its shape.

Судячи з усього, вони просто взяли реальні відхилення від сферичності і домножили їх на якийсь кінський коефіцієнт чи щось в тому роді (а може й просто робота художника) — це навіть не розрахунки в рамках якоїсь цікавої фізичної toy model :( «скучно, розходимся»

згоден з шестикутником менше запитів буде, але обчислення будуть не оптимальні для вашого сервера

Код просто будет более замороченный для шестиугольной сетки и всё.

ось це і називається «не оптимально»

Если гугл отдает строго по окружности, то как не возись, будет неоптимально. Если в своей базе — то можно в запрос сунуть искомый полигон, пусть даже границы города/района/etc и все будет

«Тут работы на 5 минут» © Говорит любой менеджер или лид.

Думаю, кривизной поверхности можно пренебречь, если Вы не хотите загрузить Гугл на пол дня, просчитывая места в радиусе 10 тыс км

в якості приколу :)
— утягнути дані у postgres
— підключити postgis
— шукати, як заманеться

(досвіду з postgres/postgis нема, якщо є підводні камені — не в курсі
але на ньому крутиться openstreetmap і не кашляє)

Я б звичайно шукав квадратами чи прямокутниками якщо так можна (це ефективніше і зручніше).

Але якщо потрібні саме кола, я б розбивав площу пошуку на рівносторонні шестикутники утворенні перекриттям кіл рівновіддалених центрів (так як встановлюють вишки сотового зв’язку), думаю, це забезпечить мінімум запитів, проте потрібно буде уніфікувати місця які знаходяться в перекритті кіл пошуку.

Приблизна картинка того що я маю на увазі тут upload.wikimedia.org/...​ircles36arcs-enclosed.png

По естімейтам тут не так просто, якщо алгоритм мені спав на думку миттєво, то якщо це реальний проект, то я б сказав, що це б зайняло 3-4 дня розробки, інтеграції і тестування з похибкою на те, що я ніколи не користувався Google Places API і пару раз юзав різні Google APIs.

Примерно так. Собственно, разбиение, которое использую я: ibb.co/nb2Xu9
Квадраты или прямоугольники для этого типа запроса нельзя использовать, только окружности.
Для целей данного эксперимента полагаем, что в задачу разработчика не входит общение с API (оно реализуется независимо), и функция только должна принять на вход координаты центра и выдать массив координат заполняющих окружностей. API при этом не задействуется.

помню, на заре аутсорсанья, где-то в конце 90-х, заказчик (кстате по гражданству немец, но из литовцев, общался по русски) ставит коллеге задачу и спрашивает оценку времени. Ответ: «Да ерунда! пару дней». Проходит порядка недели, и заказчик осторожно интересуется — а гдесопснобля? Ответ: «Ну я ж говорил — пару дней !!»

задача написать алгоритм, я даже не знаю как его растянуть на пару недель, разве что ничего не получалось почти 2 недели, а потом бац и готово

по большому счету задача — написать алгоритм нарезания шара на кружки, более того вопрос стоит «за сколько составишь и реализуешь алгоритм?», не включая обучение, теории, уточнения и прочее

Ну, какую-то часть обучения стоит тоже включить. Не знакомство с основами тригонометрии, разумеется, все мы проходили матан. Но нагуглить нужные законы и вывести из них рабочие формулы — абсолютно. Короче представьте, что вы мидл/сеньор разработчик, и вам поручили такое закодить, вы же будете тратить рабочее (а не личное) время на это. Интересует размер этого рабочего (billable) времени, вопрос чисто практический.

с таким раскладом я буду эстимейтить как обычно на среднегостатистического разработчика, чтобы задачу мог сделать любой в команде, предварительно разбив ее на кучу задач, в итоге получится эстимейт в месяцах :)

сам алгоритм и его написание пару часов, все остальное занять может неопределенный срок, т.к. у каждого своя подготовка и очень зависит от того кто будет делать, кому-то просто код написать, а кому-то математику познать

90% времени задачи занимает сделать вменяемые требования, acceptance criteria и разные ограничения. Обычно идет отписка на 2 строчки типа «сделай заебись!», а в процессе работы уже добавляют и добавляют. Неудивительно, что задача занимает месяцы вместо пары дней.

у меня были проекты, с адекватными бизнес аналитиками, где требования не надо уточнять, когда таска уже в работе, эстимейт не особо отличались

У меня таких проектов не было. Вот типичный пример как ТС пишет обтекаемые вещи, а программимст потом их реализует как сам захочет с любой погрешностью, затем добавляется новая итерация изменений и тд. Так это еще довольно подробно написано. Обычно бывает что-то типа «Integrate Sadaka» и привет )

Согласен, собственно с этой целью и вопрос: сравнить свой результат в этом плане с оценочным результатом других.
Кроме того, я вот щас этот код пишу и по факту у меня два часа даже тупо закодить по формулам не получается: вылазят всякие класные приколы типа ошибок округления (децимал не спасёт, всё равно будут разности при подсчёте корней и арксинусов), вычисления границ расчётов, градусы vs радианы в формулах и т.п.
Хотя сейчас я написал вам об этом и понял, как можно сделать по-другому, чтобы их избежать)

Реализация этой хрени достаточно проста. Сложнее будет написать тест, подтверждающий что требуемая точность достигнута в пределах +/- требуемой погрешности. Т.е. что разбиение 1) достаточно для заданной точности 2) не избыточно (т.е. не влечёт к ненужному удлинению времени рассчёта).

Коментар порушує правила спільноти і видалений модераторами.

Также должна учитываться кривизна земной поверхности.

в них є можливість шукати по висоті над рівнем моря?
чи може я щось не доганяю))

Имеется в виду, требуется учитывать, что земная поверхность не плоская, и расстояние между двумя соседними точками — это дуга, а не прямая. Тыц.

для расстояния в 10 км разница между окружностью и прямой при радиусе земли будет минимальна, нет?

Зрозуміло, це не проблема, якщо будете правильно рахувати в метрах.
Ось ваша перша функція так має виглядати github.com/...​oder/calculations.rb#L210
Щоб правильно метри порахувати github.com/...​coder/calculations.rb#L84

Ось, ще намалював jmp.sh/mwW19K5
На око видно що це трохи кода, якщо є норм ліб для геокодінгу, там більш з тестом прікол(типу довше писати).

сорі, за файл, діагональ може бути ... <= 50км * 2

Также должна учитываться кривизна земной поверхности.

Ты это, потише — щас набегут flat-earthers.

Или зануды, которые заметят, что в условии речь может идти не только о поверхности шара, но и о рельефе.

минимально возможное количество, при этом территория должна быть покрыта полностью, но с как можно меньшей погрешностью. Также должна учитываться кривизна земной поверхности.

Насколько минимальное? Как учитываться? Не хватает только кОрованов.

Підписатись на коментарі