Окрупняване на сегменти на улици посредством релации

Здравейте,
Започваме да работим по проект целящ систематизиране на етимологията на имената на улици в България. За тази цел мислим стъпим върху данните събиращи се благодарение на mapcomplete (виж тази нишка за повече информация) и същевременно да популяризираме работата с този инструмент така че да се съберат повече и по-качествени данни.

За да стане хубаво искаме да има стабилна двупосочна връзка между обект в уикиданни съответстващ на дадена улица и релация в OSM отговаряща на цялата улица.

Така етимологичната информация ще може да се съдържа в уикиданни, да сочи удобно към уикипедия и, най вече информацията че дадена улица е кръстена на дадено нещо да бъде автоматично отразена в съответната статия в уикипедия посредством шаблон.

Ето пример за такава релация 16841563, отговарящ на ул. Кукуш в София, и връзващ към съответния обект (Q123913911). Там виждаме как чрез предиката P138 се осъществява обратната връзка към OSM. Така излежда същата релация показана посредством шаблон в Уикипедия и тази връзка.

Отварям тази дискусия за да чуя какво мисли общността за генерализация на този модел и създаване на такъв подобни релации за всички Български улици в OSM, за които имаме етимологична информация?

1 Like

Преди имаше Relation:associatedStreet - OpenStreetMap Wiki, сега гледам ново предложение - Proposal:Relation:street - OpenStreetMap Wiki. По принцип си е хамалогия да се правят всички улици с релации.

Не съм сигурен, че си струва да се правят релациите с по един обект (примерно Way: ‪3014‬ (‪24843781‬) | OpenStreetMap) само заради експлицитния P138.

За машинна обработка би трябвало да е все едно към кое API ще са заявките, а интерфейсно Уикиданни са си направили кръпката с Overpass в страничното меню.

Това с релациите със само един член доста силен аргумент!

По принцип има логика, но при по-дълги улици може някой участък да стане еднопосочен, да бъде маркиран с различна настилка и т.н. ChatGTP сигурно може да измисли заявка за Overpass turbo, така че такива улици да излизат “в червено”.

Съгласен съм с Пламен, правенето на тези релации си е хамалогия. После някой ще сложи кръгово кръстовище по средата и ще стане мазало. Или пък ще решат да сменят името на част от улицата, но не и name:ethymology:wikidata, а релацията ще съдържа две улици с различни имена. Поне може да се хване лесно с Overpass turbo и малък скрипт.

От друга страна все си мисля, че ще дойде някой светъл ден, когато ще се наложи да правим такива (или type=multiline) релации, така че е по-добре да сме стъпка напред.

Другият вариант е да се създадат обекти за улиците в уикидата и да се сочи едно към много към тях от ОСМ с ключ wikidata=. Ако някой ми помогне да се ориентирам с масовата редакция в осм предлагам следния работен процес:

1/ вадим всички сегменти на улици от ОСМ и ги групираме по име. Тук ще има известна доза чистене и хомогенизиране на имена но няма да е много болезнено и има туулинг за това
2/ за всеки един такъв сегмент търсим дали има обект в уикиданни и ако няма създаваме
3/ за всеки такъв обект в уикиданни популираме ОСМ wikidata= ключа с нegoвото ID във всеки сегмент отговарящ на улицата.
4/ всяка улица в уикиданни популираме с етимологичната информация която в момента се краудсорс на ниво сегмент

Така резултатът е че за всяка улица ще има обект в уикиданни, който вече ще може да се ползва в уикипедия. Той ще бъде определен от множеството сегменти в ОСМ които сочат към него. Ако направят кръгово, то новите сегменти от кръговото ще трябва да имат и съответния wikidata id за да бъдат считани като част от улицата.

Ако името на улицата се смени ще трябва да се смени и в уикидата и във всеки един сегмент в ОСМ.
Също може да мислим за някакви валидации, применро за улиц на които имената в осм не са изписани еднакво и те да се поправят в името на по-чистите данни.

Какво мислите?

На пръв прочит звучи добре.

За масова редакция може да пробваш JOSM или Lelevl0 (текстов редактор).

Като последна стъпка, може да вземеш официалните данни от МРРБ (Open Data Portal) и да видиш кои улици липсват в OSM по населени места. Кода на населеното място е неговото ЕКАТТЕ, кода на локализационната единица си е техен номер.

С JOSM могат да се изкарат всички сегменти, включително несвързани такива. Отделно трябва да определиш в кое населено място са. Но най-вече се питам - струва ли си всичко това и някъде изобщо правено ли е?

За мен си струва защото това е вид културно наследство. Изкомуникирано по правилния начин може да ангажира повече хората със средата в която живеят.

Аз докато си играех с приложението за навръзване на етимологията например научих супер интересни неща. Направих си също екперимент като го показах в кварталната ФБ група и на хората им стана интересно и се получиха смислени дискусии.

Благодаря за отговорите. В крайна сметка решихме да не правим релации а окрупняването да става в Уикиданни, като от ОСМ връзката е много към 1 с wikidata= таг.
Първата част от работата я свършихме. За всяка софийска улица има обект в Уикдианни.

Сега обаче бедствам да запиша въпросните тагове в ОСМ. Много са и средите са ми сложни и неудобни. Някой може ли да ми помогне? :pray:
Ето това е файла със съответствията, само трябва wikidata идентификатора да се запише с таг wikidata= в съответните обекти.

Успях да направя скрипт на JS, който генерира OSM change файлове. Само не мога да ги кача, понеже съм на друг компютър. На места се появява странен дефект - някои български букви стават на квадрати или ромбове с въпросителни… Единствения възможен проблем е в моя телевизор, но все пак виж да не ги прави така и при теб.

Таблицата я конвертирах в JSON файл с CSV to JSON - CSVJSON.

П.С. Добавих около 100-150 Wikidata тага полу ръчно. Скрипта е умен и ако види същия таг, не го добавя пак. Ако има конфликт (т.е. пътя има wikidata, но не този който искаш), го игнорира.

const fs = require("fs");
const https = require("https");
 
const MAX_OBJECTS_PER_OSC_FILE = 500;
 
const wikidata_data = JSON.parse(fs.readFileSync("osm_wikidata.json"));
 
const obj_ids = wikidata_data.map((el, index) => `way(id:${el.id});`).join("");
const data = ("data=[out:json];("+obj_ids+");out meta;");
 
 
//fetch data from overpass turbo
const options = {
	hostname: "overpass-api.de",
	path: "/api/interpreter",
	method: "POST",
	headers: {
		"Content-Type": "application/json",
		"content-Length": data.length
	},
	rejectUnauthorized: false
};
 
const req = https.request(options, (res)=>{
	responseData = "";
 
	res.on('data', (chunk) => {
		responseData += chunk;
	});
 
	res.on('end', ()=> {
		match_data(JSON.parse(responseData));
	});
});
 
function match_data(osm_data){
	//match wikidata value to each element
	var result = [];
	var conflicts = [];
	var ignored = [];
	osm_data.elements.forEach(el => {
		var desired_wikidata = wikidata_data.find(wd_el => wd_el.id == el.id).wikidata;
		if(el.tags.wikidata){
			if(el.tags.wikidata == desired_wikidata){
				ignored.push(el.id);
			}
			else{
				conflicts.push(el.id);
			}
		}
		else{
			el.tags.wikidata = desired_wikidata;
			result.push(el);
		}
	});
 
	console.log("conflicts:" + conflicts);
	console.log("ignored:" + ignored);
	console.log("Total tags for adding: "+result.length);
 
	generateOSCFiles(result);
}
 
function generateOSCFiles(data){
	var page_counter = 1;
	var cur_data = '<?xml version="1.0" encoding="UTF-8"?><osmChange version="0.6" generator="Level0 v1.2"><modify>';
	data.forEach((el, index) => {
		if(Math.floor(index/MAX_OBJECTS_PER_OSC_FILE)==page_counter){
			cur_data += `</modify></osmChange>`;
			fs.writeFileSync(`output/out.${page_counter}.osc`, cur_data);
			page_counter++;
			cur_data = '<?xml version="1.0" encoding="UTF-8"?><osmChange version="0.6" generator="Custom script"><modify>';
		}
		cur_data += `<way id='${el.id}' version='${el.version}' changeset='1234' timestamp='${el.timestamp}'>`;
		el.nodes.forEach(node => {
			cur_data += `<nd ref='${node}' />`;
		});
		Object.keys(el.tags).forEach(key => {
			cur_data += `<tag k='${key}' v='${el.tags[key].replace("'", "&#039;")}' />`;
		});
		cur_data += `</way>`;
	});
}
 
//execute request
req.write(data);
req.end();

Добре сте ги импортнали улиците в Wikidata. Само да попитам, ако сте ползвали списъка от

Защо не импортнахте и това странно нещо - код на локализационна единица?
Аз малко се поизмъчих да го добавя ръчно, ако някой има познания по Wikidata може ли да коментира. Би трябвало да е ‘external identifier’. Поне така на прословутата Oxford Street има Unique Street Reference Number. Въпросният номер обаче е UK ориентиран (8 digit number assigned to streets, roads, footpaths or public rights of way in the United Kingdom). Бих искал да добавим подобен код и за България. Би трябвало да е property (P*****). Някой има ли идея как да стане това в Wikidata? Някъде пишеше, че подобни неща трябва да преминат през обсъждане, гласуване и т.н.

2 Likes

О да! Това трябва да влезне в уикидата като външен идентификатор и системно да се импортват всички единици от този ресурс.
Ще задвижа там бюрокрацията за регистриране на нов предикат и когато е готово ще дам знак.
Може ли междувременно да набутате уикидата индентификаторите на съществуващите обекти в ОСМ. Те ще са нужни за да се синхронизира всичко накрая.

Вече са вкарани. Останаха обаче дупки (понеже доста улици бяха нарязани при добавянето на границите на кварталите). Ако можеш, генерирай наново CSV файла.

Задвижих процеса в уикиданни. Ако имате възможност оставете по един палец в гласуването тук

По-важното, обаче е че гледайки класификатора забелязах че 5-цифрения код не е уникален. Уникален е когато е комбиниран с петте цифри на ЕКАТТЕ. Това може да обърка малко нещата и затова ме сърби да го регистрирам като 10 цифрен код в уикиданни като разделя двете с точка или тире.

  • Ул. “Хубавка” в София (екатте: 68134) е с код 18798.
  • Ул “Херакъл” във Варна (екатте: 10135) също е с код 18798 .

Въпросът ми е дали да записваме неуникалните стойности 18798 в Уикиданни или да запишем нещо от рода на 68134-18798 и 10135-18798. Аз клоня към второто.
Как мислите? Има ли някакв логикаа която би се счупила в следствие на такова решение?

Сега видях следното в Уикиданни:

street key (P1945)

identification number for a specific street within the street cadastre of a municipality

Което може би ще свърши работа, без да се налага да се въвежда нов код.

И да, кодът е уникален за населено място, но след като има въведено и
“в административно-териториалната единица (P131)” напр. Варна,
не виждам смисъл и в някакви сложни кодове.

Само да спомена, че P131 може и да не е населеното място, а район (а районите не са вложени в населено място, а в община…), както и да има няколко стойности. Т.е. не е съвсем праволнейно да се стигне до ЕКАТТЕ-то.

Но и залепването на ЕКАТТЕ кода си има недостатъци (дублиране на данни = възможен проблем).

Това го бях изпуснал. Наистина може би е по-адаптирано без да товарим WD с още един код.
Може даже екатте кода да се запише и като класификатор на самото твърдение, както каталога. Сега ще дам пример в дискусията под порпузъла

Решихме че няма смисъл да товарим WD с още една релация и ще ползваме P1945, съчетана с P131, сочеста към населеното място. Ето пример с Цариградско шосе, което минава през няколко населени места. Съответно:

68134-60112 (Sofia), 
14831-60112 (German), 
99139-60112 (Gorubliane), 
44063-60112 (Lozen)

Отговаря на

и

Прав си. Там трябва малко ресане и отсяване посредством клас и квалификатори.

Честно казано мен доста ме дразни че така сме натоварили P3990 с два кода (виж Пловдив примерно) това с буквите и цифрите (PDV22-00), на което НСИ му казват KMETSTVO всъщност трябва да е LAU (P782) и просто както го има на ниво община трябва да го има и на ниво община и кметство.
Ако има някой навит да помага може да седнем и да преправим данните