Comments 49
коды GeoNames для городов и штатов
А почему именно GeoNames? Это, вроде, не стандарт. Для "штатов" (административного деления) есть тот же ISO 3166-2.
Ещё один плюс GeoNames – идентификаторы уникальны для всей планеты. Необязательно хранить код страны рядом с кодом области.
Потому что есть ещё города, а для них нет никаких стандартных кодов, насколько я знаю
Так чем GeoNames лучше любой другой системы идентификации, хотя бы и собственной?
Если у меня имеется 5 приложений и всем нужны географические данные, мне проще на всех 5 использовать идентификаторы GeoNames, чем 1) использовать 5 разных наборов 2) придумывать свою конвенцию.
А если выбирать не из своих систем – я не смог ничего глобального найти кроме GeoNames. Если есть что-то еще – то надо будет просто добавить эту систему в пакет, разработчик сможет выбрать, чему он больше доверяет в долгосрочной перспективе :)
Уменьшением зависимостей, или то что в английском называется 'decoupling'.
Ровно наоборот, вы не уменьшили зависимости, а добавили еще одну — от GeoNames.
Если приложение было одно – вы заменили собственную кустарную (живущую в адресном пространстве конкретного приложения) зависимость – глобальной, стандартизированной, проверенной годами. Что не так уж и плохо само по себе! ;-)
Если приложений было 5 – вы заменили 5 зависимостей всего одной.
Нет, потому что
(а) зависимости считаются для каждого приложения отдельно и
(б) собственный код не является зависимостью.
вы заменили собственную кустарную (живущую в адресном пространстве конкретного приложения) зависимость
Собственный классификатор не является зависимостью.
глобальной, стандартизированной, проверенной годами
GeoNames разве стандарт?
Лично мне было бы удобно, что во всех моих приложениях код города 15 – это город X, и при этом мне не надо самому ничего документировать.
GeoNames – это, как говорится, не идеально, но лучшее, что у нас сегодня есть.
Но все еще настаиваю на том, что работать в будущем (то, что называют термином 'maintainability') будет проще с приложением, использующим известные, документированные API и конвенции.
Только в том случае, если эта конвенция (а) удобна для приложения (а не надо ее натягивать специально) и (б) известно, что она не изменится.
GeoNames – это, как говорится, не идеально, но лучшее, что у нас сегодня есть.
Кстати, что произойдет в GeoNames, если какой-то город переименуют? Или, что хуже, произойдет административная реорганизация?
… и что случится в этот момент в вашем интерфейсе в поле "пользователь родился в"?
И это только переименование. А представьте себе, что город удалили (или он разделился на две части). Или представьте себе, что пользователь хочет зачекиниться в городе, которого нет в GeoNames.
Пропадать города будут очень, очень редко. Не уверен, как GeoNames поступают в таких случаях. Если просто удаляют из базы навсегда — то да, надо думать как такие случаи обрабатывать.
В GeoNames есть все города с населением выше 1000 людей — этого достаточно должно быть большинству приложений.
Facebook, к примеру, имея миллиарды капитала, не может до сих пор многие ошибки в географии исправить. Подозреваю, что качество данных было бы выше, если бы любой пользователь мог исправлять ошибки (а в случае пакета на GitHub так и будет)
Вообще, все нормально будет — скажем, до 1991-ого года пользователь имел «родился в Ленинграде», после 91-ого «родился в Санкт-Петербурге» (что абсолютно верно)
Это с вашей точки зрения верно, а с его — не обязательно.
В GeoNames есть все города с населением выше 1000 людей — этого достаточно должно быть большинству приложений.
Что делать тем, которым недостаточно?
Подозреваю, что качество данных было бы выше, если бы любой пользователь мог исправлять ошибки (а в случае пакета на GitHub так и будет)
Вы совершенно зря так подозреваете. Даже GeoNames для предоставления более достоверных данных использует ручное курирование.
А главное, что делать, когда интересы пользователей конфликтуют? Например, для одного приложения нужно, чтобы Крым и Севастополь были частью Российской Федерации, для другого — чтобы нет. Как вы будете нормализовать иерархию в этом случае?
Если мой пакет будет полезен даже для 50% приложений – это уже будет прекрасный результат.
А использование собственной разработки или доработки, когда общедоступные реализации немного не подходят – это совершенно нормальное явление, его мы наблюдаем ежедневно. Всем не угодить, задача угодить многим :)
Про оспариваемые территории я пока еще думаю над решением :)
Речь не о пакете. Речь о предлагаемом подходе
Предвижу вопросы вроде «но как же тогда запоминать город пользователя?», и ответ тут достаточно прост – в своей БД (или куда вы там записываете данные) используйте стандартные идентификаторы, такие как коды ISO 3166-1 для стран, коды GeoNames для городов и штатов.
Особенно неприятно будет, если мы сначала на него обопремся, а потом через год выяснится, что нам нужно использовать значение, отличное от "стандартного идентификатора".
Расформирован в связи с реорганизацией (удален, разделен, присоединен) — флаг депрекейтед. В зависимости от задачи — или не давать новым указывать, но старых оставлять или давать, но рекомендовать не использовать и т.п.
Неизвестный город? Тут или ручной ввод разрешать или выбирать более общий вариант — область, район, штат, страна…
Переименован — выводим новое имя.
Это не всегда верно.
Неизвестный город? Тут или ручной ввод разрешать
Как только вы разрешаете ручной ввод, вы теряете возможность использовать внешние коды как собственные первичные идентификаторы.
А вообще у каждого своя задача, но некоторый меинстрим существует, и под некритичные задачи что-то универсальное сделать можно. А дальше форкать…
О том, что в магазине нужно давать человеку максимальную свободу я с Вами согласен полностью.
GUID в рамках всей базы и галочка «не нормализован» для ручного ввода, с последующей заменой на нормализованное значение когда админ до этого доберется.
Вот именно поэтому и не надо использовать значения из GeoNames в качестве внутренних идентификаторов.
Но именно поэтому я больше сторонник решения с деградацией до страны, чем ручным вводом.
А так вы теряете пользовательские данные.
Если это форум/социалка и т.п., то указание населенного пункта с точностью до ближайшего пгт (а 1к+ в основном в базе есть) будет вполне себе нормальным вариантом.
Да, согласен с Вами что такая библиотека не будет такой функциональной как момент, и надо будет пилить под задачу, но в качестве дефолтной фишки вполне себе хорошо было бы иметь.
Ну это от задачи зависит.
Вот я и написал: в зависимости от задачи формат хранения отличается — но при этом видно, что задач, где можно использовать сторонний идентификатор как основной, не так уж и много.
но в качестве дефолтной фишки вполне себе хорошо было бы иметь.
Хорошо иметь сервис, который умеет отвечать на геозапросы (причем совершенно разных видов), но вот откуда для него брать данные — мне не очень понятно. Предложенная ниже идея аггрегации выглядит наиболее интересной, но это большая задача.
Даже самые простые сайты, как правило, имеют список стран или городов на какой-нибудь из своих страниц – магазины хотят знать, куда доставлять товары; социальные сети хотят знать, откуда пользователь; и так далее.
Надо заметить, кстати, что в зависимости от задачи формат хранения — разный. Там где соцсеть может себе позволить делать любую нормализацию (потому что эти данные нужны ей и только ей самой), магазин — и вообще любая доставка — должны позволять пользователю ввести адрес так, как тот считает нужным. Да, с подсказками и предложениями исправить предположительно неправильное название, но без иллюзий о том, что магазин лучше знает, как выглядит нужный пользователю адрес.
А тут в Австралии так вообще — любят принудительное распознавание адреса. Если сайт не смог распознать (интерпретировать) адрес — пользователь не может продолжить. Таким образом, можно использовать подобный пакет без проблем (точнее даже — он уменьшит количество проблем :)
Ну, выбор страны как правило
Выбор страны можно сделать и по ISO.
А тут в Австралии так вообще — любят принудительное распознавание адреса. Если сайт не смог распознать (интерпретировать) адрес — пользователь не может продолжить.
Сочувствую. Фишка, однако же, в том, что Австралией мир не ограничивается.
Про Австралию согласен, это так – пример. Про адреса в свободной форме, мне кажется, было бы полезным какой-то умный парсер адресов сделать, который умеет приводить адреса вроде «УЛ НИКИТИНА МОСКВА» в «ул. Никитина, Москва, 125000 Россия». Точно знаю, что некоторым проектам это нужно
Выбор – можно по ISO, а как пользователю отображать?
Речь в этой ветке идет о формате хранения, а не отображения.
Про адреса в свободной форме, мне кажется, было бы полезным какой-то умный парсер адресов сделать, который умеет приводить адреса вроде «УЛ НИКИТИНА МОСКВА» в «ул. Никитина, Москва, 125000 Россия». Точно знаю, что некоторым проектам это нужно
Некоторым, но не всем. Именно поэтому я и говорю, что реальный формат хранения сильно зависит от задачи.
А парсеры такие есть, и на хабре их уже неоднократно упоминали (по крайней мере, в части России), но они, очевидно, языкоспецифичны.
Нормализация представления нужна.
В 1С есть такой парсер адресов, и работает примерно так:
* Нормализует введённую строку (по классификатору адресов),
* в базу записывает 3 значения: Код по классификатору, нормализованная строка, строка «как есть» от пользователя (кстати, данные в КЛАДР хранятся в очень понятном формате ключ-значение).
Я эту сохранялку адресов пару раз подгонял под новые стандарты компании, потому знаю, как оно внутри устроено.
Нормализация представления нужна.
Всем и всегда?
Мне, как программисту — нужна.
Ну, будем честными, пользователя это не очень волнует.
Почте России тоже нужна, у них нормализованные адреса на конверте писать надо.
Эээ, правда? Я несколько лет шлю по России открытки с адресами в формате "как сегодня проснулся", еще и латиницей часто — и ничего, доходит.
Старался сделать все максимально рационально.
Объект Planet всегда один и тот же, и это всегда Земля:
/**
* @return string
*/
public function getShortName()
{
return 'Earth';
}
/**
* @return string
*/
public function getLongName()
{
return 'The Blue Marble';
}
Как минимум, в примере надо сделать имя переменной $earth, чтобы логика соблюдалась :) И объявить, что другие планеты создавать (как перевести instantiate?) пока нельзя
Насчет интерфейсов — я пока склоняюсь (на GitHub код уже видно) к абстрактному классу для всех видов делений вместо интерфейсов для разных уровней делений. Есть класс Divisible (делимый), и пока что логика планеты, стран и штатов почти полностью совпадает — это решение пока похоже на оптимальное.
А вот что реально было бы хорошо иметь, это разные источники данных, база/файлы/пусть даже интернет. Плюс сделать возможность кеширования тех данных что ты вытаскиваешь.
Поиск по координатам, как я понял устроен топорно и просто сравнивает значения? Это плохо. В некоторых базах есть возможность искать координату приблизительно, да и алгоритмы для поиска есть. Это конечно в пределах пхп работать будет не очень быстро, но хотя бы честно.
Вещи типа useShortNames не совсем понимаю зачем? Если можно возвращать в том же массиве оба варианта. Метод inflict мне тоже не понятен, почему это должна делать библиотека, которая используется как база данных?
В общем, проще засунуть эти данные в монгу, взять какой-нибудь ODM, и будет так же хорошо, и даже намного лучше, ибо сложные запросы, поиск по координатам и т.д.
А вот что реально было бы хорошо иметь, это разные источники данных, база/файлы/пусть даже интернет. Плюс сделать возможность кеширования тех данных что ты вытаскиваешь.
Про это я уже думаю :)
Поиск по координатам, как я понял устроен топорно и просто сравнивает значения? Это плохо. В некоторых базах есть возможность искать координату приблизительно, да и алгоритмы для поиска есть. Это конечно в пределах пхп работать будет не очень быстро, но хотя бы честно.
Поиска пока нет вообще – он просто показан в примере. В современных БД есть гео-индексы. Как поступить тут и сохранить при этом маленький размер – я ещё думаю.
Вещи типа useShortNames не совсем понимаю зачем? Если можно возвращать в том же массиве оба варианта. Метод inflict мне тоже не понятен, почему это должна делать библиотека, которая используется как база данных?
Сначала так и было – два варианта. Ход мыслей дальше был такой: длинный (полный) вариант есть всегда, короткий иногда. Если возвращать оба поля и одно из них может быть пустым – разработчику придется на своей стороне (приложения) делать условия, а условия уже давно никто не любит.
То есть, если я могу попросить useShortNames(), то после этого я могу просто отображать одно поле, а пакет его выбирает по принципу best effort (старались как могли).
Inflict() – потому что больше половины сайтов до сих пор не умеют правильно склонять слова русского языка. Скажем, у нас есть какая-то лента или стена, и там есть подписи вроде: «Написал Иван 5 минут назад из Владивостока». Где хранить правильную форму имени города?
В общем, проще засунуть эти данные в монгу, взять какой-нибудь ODM, и будет так же хорошо, и даже намного лучше, ибо сложные запросы, поиск по координатам и т.д.
Так все и делают, включая меня – и это занимает много времени, требует установки дополнительных сервисов и так далее. Было бы очень классно иметь легкую, независимую (от внешних демонов) библиотеку, которая покрывает хотя бы все базовые требования.
А в Symfony Intl есть удобная абстракция над большинством справочных материалов intl, причем все с использованием iso, а не велосипедия.
Если сайт на, скажем, английском, и нужен просто список стран — то можно intl использовать.
Есть много много разных БД, и для разных целей и разных местностей подходят разные базы. Например для России есть регулярно обновляемый КЛАДР, но в нем только адреса, нет геокоординат, нет возможности искать по запросам типа «Кафе у Ашота», и она не переведена на другие языки. У других стран есть свои подобные базы, есть базы OpenStreet, но у всех чего-то не хватает.
В общем, было бы хорошо иметь такую аггрегированную базу всего, и пакет, который бы к с ней работал, но подозреваю, что в итоге получится что-то типа геосервисов Гугла или Яндекса, который одному человеку не потянуть.
Однозначно, да!
Тривиальная задача, особенно актуальна для разработки сайтов (небольших проектов), т.к. надоедает просто копировать дамп базы из проекта в проект, при этом нужно поддерживать актуальность списка стран, регионов/штатов, городов.
Так же надо учитывать тот факт, что в бд может хранится ненужные геоданные, например, про Африку, что не совсем нужно, когда проект не ориентирован на ее жителей.
То же касается и языков. Далеко не каждому сайту нужно более 3-4 языков. Имхо.
1) Сами данные будут подгружаться в режиме ленивой загрузи
2) Если базы станут большими, я думаю детализированные базы по странам можно будет выделить в отдельные репозитории. Тогда в начале разработчику просто 2+ пакета надо будет устанавливать — основной и необходимая база, набор языков
Пакет-географ или библиотека, которая прекрасно знает географию и говорит на разных языках