Как стать автором
Обновить

Комментарии 24

Написано очень эмоционально, но немного непонятно.

Я могу воспользоваться этим сервисом и нарисовать границы районов Парижа, Франция на Google Maps?
Или отобразить границы neighborhoods в San Francisco?

Спасибо.
Париж? Это который №71525? Берем и показываем — jsfiddle.net/9o9ak7fb/24/
Перевод в коллекции G или Y карт, и даже приведение в некий общий интерфейс тут есть.
osmeRegions.geoJSON(71525/*Париж*/, {
            lang: 'ru', 
            quality:0,
        }, function (data, pure) {
            if(mtype=='Y'){
                collection = osmeRegions.toYandex(data, ymaps);
                collection.add(geoMap);    
                geoMap.setBounds(collection.collection.getBounds(), {duration: 300});
            }else{
                collection = osmeRegions.toGoogle(data);
                collection.add(geoMap);    
                Gzoom(geoMap,collection.collection);
            }
            
    });


Соседи US-CA? Настраиваем схему и показываем — jsfiddle.net/9o9ak7fb/25/
osmeRegions.geoJSON('US-CA', {
            lang: 'en', 
            quality:0,
            scheme: {
                165475:function (region){
// Для 165475(калифорния) выборка всех соседей СанФранциско.
                return region.hasBorderWith(396487) && region.osmId!=396487;
            }
            },
            postFilter: function (region){
// Оставляем только Калифорнию
                return region.osmId==165475;
            }
        }
Спасибо.

Еще вопрос — обязательно ли подключать Yandex Maps API? Он подключен везде в примерах на jsfiddle.

Под San Francisco neighborhoods я подразумевал примерно такую карту (районы города):

San Francisco neighborhoods

Без больших названий районов, разумеется.
Карта отсюда.
Яндекс Карты не обязательны, вот районов нужных нет, как и всех внутренностей Египта, половины Китая и тд. Ничто не идеально :(
В OSM отмечены данные районы как точки, а в Wiki прописано, что данные единицы не имеют четких границ и рекомендуется отмечать просто точкой. Потому думаю в большинстве случаев не будет их ни у кого, если только кто-то не нанесет их сам.
Границы есть только для отношений с тэгом boundary=administrative + admin_level=*
В моем случае есть еще два хитрый момента:
1. В данные попали не всегда верные файлы — например церковные приходы
2. В экспорт попали только те данные, которые смогли замкнуться в контур. Очень многие relations, к сожалению, не смогли.
3. За время подготовки данных многие relations изменились или были вообще стерты.
Сейчас есть заново обработанные данные, чуть более корректные. Но пока не в проде.
По районам что LA, что Подольска или Мытищ ситуация одинаковая — они вроде как есть, но не совсем публичные. При этом всегда можно взять геометрию улиц, и собрать из них районы, кварталы, зоны обслуживания почтовых отделений…
При этом всегда можно взять геометрию улиц, и собрать из них районы, кварталы, зоны обслуживания почтовых отделений…

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

У нас есть похожаю выгрузка, в ней получилось 254505 объектов административных границ. Если верить taginfo, всего отношений-границ 286 987.

Сейчас есть заново обработанные данные, чуть более корректные.

Чем обрабатываете и на чем?
У меня в базе 195к обьектов которые смогли собраться хотя бы в один контур. Из них 20 тысяч ушли в «дубликаты» — в OSM 3 или 4 Парижа вложенных друг в друга, три Амстердама и тд…
Обрабатываю самописными ручками. В начале экспорт из planet файла, потом две стадии предобработки ways, потом сборка, потом связка с родителями, потом мержинг с внешними БД (geoNames, booking итд).
Потом понимаешь, что в NY у тебя находится в Бруклине, и таблице регионов у него admin_level=8, и совершенно не понятно почему, когда, кто виноват....
Посмотрел Париж, там не все так однозначно, да есть два Парижа, но они являются разными административными единицами в составе Франции, ИМХО не совсем корректно так сливать их.
Еще возник вопрос на примере NY, согласно вашей схеме (визуализации) у вас слились воедино NY город и NY штат, возможно для вашей задачи это не критично, но все же вводит в заблуждение.
NY и NewYorkCity — две большие разницы.
Один — OpenStreetMap 175905, GeoNames 7163824, Wikipedia ru: Нью-Йорк
Второй — OpenStreetMap 61320, GeoNames 5128638, Wikipedia ru: Нью-Йорк (штат)
Да — называются одинаково, но все так и есть. И тот, который имеет ISO3166-2 код US-NY — штат.

С Парижем все хитрее — не стоит забывать, что базу в общем случае делал для себя. И для «пользователей».
Если человек три раза тыкает мышкой и не может попасть «ниже» — это не совсем правильно.
В итоге — в экспорте «поID» есть все регионы, и у всех есть полный перечень их «родителей» (ну почти*). Но вниз спускается хитро:
Для «стран» — спуск до прямых детей, и до регионов второго уровня. Так в России есть и ФО(дети) и Регионы(ISO). Тоже самое с Крымом — он вообще геометрически в контуре Украины. Но по ISO — в России.
В «Парижах» примерно тоже самое — под детьми подразумеваются те, чей родитель вы, или ваш «клон».

(ну почти*) вот в Париже поле parents у райнов или пустое, или кривое, сейчас поправим :(
О, поскольку вы в теме, хочу спросить, нет или в Яндексе, Гугле, или еще где либо возможности подсветить административные единицы уровня района или области? Не так, чтобы я вручную создал пару сотен или тысяч полигонов, а автоматического деления и команд вроде highlightRegion('Crimea')? Мне нужно вывести статистику по районам, то есть подсветить его, и напечатать поверх некоторые цифры.
Вы не поверите — именно для этого данная чтука и создана. В каждый файл входит как контур запрашиваемого обьекта, так и контура его подразбиений. Плюс вся нужная информация — кто кому родитель, ссылки на википедию и тд и тп.
Надо просто знать где этот крым — 72639 или 'RU-CR'. По этим именам и он доступен.
А саму базу опубликовать не собираетесь?
Раз уж ваши данные основаны на OSM, то как я понимаю,
в соответствии с лицензией ODbL www.openstreetmap.org/copyright
пункт 4.6 Access to Derivative Databases вы обязаны выложить ее в открытый доступ.
На гитхабе лежит github.com/theKashey/osme, который может собрать «такую» базу данных. В принципе этого достаточно для соблюдения условий дериватива «как базы данных». Но данный сервис никаким боком не БД, а обычный Produced Work, те на него распространяется пункт 4.3
А вообще если OSM был бы не таким манерным и сам бы замержился с тем же GeoNames — мир стал бы лучше. Но нет, нельзя.....

А где сейчас лежит osme, если ещё где-то лежит, конечно?

За прошедшие два года я успел: допилить геокодер, переписать регионы на es6, обзавестись третим сыном и переехать в Австралию.
Чего не успел — добиться стабильной сборки геометрии одной командой с консоли.
А osme некоторое время назад пришлось скрыть из-за некоторых моментов, которые не очень дружат с опенсорсом.
В данный момент переписываю. В моих интересах выложить его куда либо, чтобы получить помощь других разработчиков и снять это ярмо(tech debt) с шеи.
Долго пытался это к LeafLet применить, в итоге вот простой пример:

osmeRegions.geoJSON('ru', {
  lang: 'ru', 
  quality:2,
  type: 'coast'
  }, function (data, pure) {
      var geojson = new L.geoJson(data).addTo(map);
});
Думаю стоит добавить его в примеры. Эх, еще бы кто интерактивность для Леафлета докрутил…
Пока вы тут и быстро реагируете, задам вопрос.
Как использовать osmeRegions на локальном хосте, без интернета?
С учётом того, что ответ с data.esosedi.org закеширован.
Не хочется лезть в чужой код, но вижу что производятся какие-то преобразования ответа, в чистом виде он совсем не GeoJSON.
Формат там достаточно упоротый, и по сути нужен только для передачи данных.
Вариантов использования на локалхосте парочка:
1. Сохранить себе geoJSON. В принципе из .geoJSON он выходит в чистом виде.
2. Сохранить себе «оригинальные данные», парсить в geoJSON через osmeRegions.parseData.
3. Изменить хост (.setHost) или функцию .loadData так, чтобы ходить в свою проксирующую «ручку».
И тут же, возникла проблема с 180м меридианом, которая решается патчем к regions.js:

Патч
# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- a/<html>regions.js (<b>12.10.2015 14:40:57</b>)</html>
+++ b/<html><b>Текущий файл</b></html>
@@ -93,6 +93,10 @@

             while (index < byteVectorLength) {
                 var position = [clampy(read() * fx + bounds[0][0]), clampx(read() * fy + bounds[0][1])];
+                if (position[1]<0) {
+                    position[1] = 360+position[1];
+                }
                 result.push([position[1], position[0]]);
             }
             return result;

Это не правильное решение, так как вводятся "unbounded" координаты, те что-то запределами -180:180. Яндекс.Карты, например их не понимают. Google Maps вообще тоже — такой формат координат в принципе недопустим в geojson.
Суть в отсутствие алгоритма shortestPath в Лефлете, и это проблема Леафлета. В том числе он тут не совсем корректно воспроизведен, в том числе потому что должен работать уже после проекции.

Имеет смысл произвести специальную обработку координат перед тем как отдать их в L, раз ему нужно. Но не будет правильным решением впиливать это в основной блок декодирования.
"Правильный" shortestPath

function getShortestPath (contour) {
    var halfWorld = 180;
    var result = [contour[0]], point = contour[0];
    for (var i = 1, l = contour.length; i < l; ++i) {
        var delta = point[1] - contour[i][1];
        if (Math.abs(delta) > halfWorld) {
            delta = delta < 0 ? -360:360;
        } else {
            delta = 0;
        }

        var nextPoint = [contour[i][0], contour[i][1] + delta]
        result.push(nextPoint);
        point = nextPoint;
    }
    return result;
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации