Попробую сделать.
upd. Сделал
Вот в этом месте несколько улиц не пофиксились
https://www.openstreetmap.org/way/428721212#map=16/48.9285/34.4878
Вот в этом месте несколько улиц не пофиксились
https://www.openstreetmap.org/way/428721212#map=16/48.9285/34.4878
Хм. Я выбирал улицы с последней правкой от Царичанська РДА.
Есть идеи как довыбрать оставшиеся?
Не хотелось бы по всему квадрату запускать замены - мало ли что можно сломать.
algot:Вот в этом месте несколько улиц не пофиксились
https://www.openstreetmap.org/way/428721212#map=16/48.9285/34.4878Хм. Я выбирал улицы с последней правкой от Царичанська РДА.
Есть идеи как довыбрать оставшиеся?
Не хотелось бы по всему квадрату запускать замены - мало ли что можно сломать.
Найти все, где их правка была предпоследней, посмотреть, что выйдет и так далее.
Найти все, где их правка была предпоследней, посмотреть, что выйдет и так далее.
Я делал запрос через Overpass:
http://overpass-turbo.eu/s/hvu
В описании языка нашел только вот это:
http://wiki.openstreetmap.org/wiki/RU:Overpass_API/Overpass_QL#By_user_.28user.2C_uid.29
Похоже, запросов для предпоследней правки нет
Остаётся разве что качать все ченжсеты юзера.
Но для этого у меня пока что инструментов нет.
Вторая партия:
http://nrenner.github.io/achavi/?changeset=41036839
Вот код для получения списка линий:
using System;
using System.Collections.Generic;
using System.Net;
using System.Xml;
namespace ConsoleApplication32
{
class Program
{
static void Main(string[] args)
{
HashSet<string> chIds = new HashSet<string>();
HashSet<string> ways = new HashSet<string>();
bool lastpage = false;
string lastTime = "2099-01-01";
while (!lastpage)
{
XmlDocument doc1 = new XmlDocument();
doc1.LoadXml(new WebClient().DownloadString(
"http://www.openstreetmap.org/api/0.6/changesets?user=3949783&time=2001-01-01," + lastTime));
var changesetsList = doc1.DocumentElement.SelectNodes("/osm/changeset");
lastpage = changesetsList.Count != 100;
lastTime = (changesetsList[changesetsList.Count - 1] as XmlElement).GetAttribute("created_at");
foreach (XmlElement changeset in changesetsList)
chIds.Add(changeset.GetAttribute("id"));
Console.Write(".");
}
Console.WriteLine();
Console.WriteLine("Changesets found: " + chIds.Count);
foreach (string id in chIds)
{
string changeSet = new WebClient().DownloadString(
"http://www.openstreetmap.org/api/0.6/changeset/" + id + "/download");
XmlDocument doc2 = new XmlDocument();
doc2.LoadXml(changeSet);
foreach (XmlElement way in doc2.DocumentElement.SelectNodes("/osmChange/modify/way"))
ways.Add(way.GetAttribute("id"));
foreach (XmlElement way in doc2.DocumentElement.SelectNodes("/osmChange/create/way"))
ways.Add(way.GetAttribute("id"));
Console.Write(".");
}
Console.WriteLine();
Console.WriteLine(string.Join(", ", ways));
}
}
}
Вот код для переименования:
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
namespace ConsoleApplication31
{
class Program
{
static void RemoveTag(XmlElement osmObj, string tagName)
{
foreach (XmlElement tag in osmObj.SelectNodes("tag"))
if (tag.Attributes["k"].InnerText == tagName)
{
osmObj.RemoveChild(tag);
osmObj.SetAttribute("action", "modify");
return;
}
}
static void SetTag(XmlElement osmObj, string tagName, string tagValue)
{
if (tagValue == null)
{
RemoveTag(osmObj, tagName);
return;
}
foreach (XmlElement tag in osmObj.SelectNodes("tag"))
if (tag.Attributes["k"].InnerText == tagName)
{
if (tag.Attributes["v"].InnerText == tagValue)
return;
tag.Attributes["v"].InnerText = tagValue;
osmObj.SetAttribute("action", "modify");
return;
}
var newTag = osmObj.OwnerDocument.CreateElement("tag");
newTag.SetAttribute("k", tagName);
newTag.SetAttribute("v", tagValue);
osmObj.AppendChild(newTag);
osmObj.SetAttribute("action", "modify");
}
static string GetTag(XmlElement osmObj, string tagName)
{
foreach (XmlElement tag in osmObj.SelectNodes("tag"))
if (tag.Attributes["k"].InnerText == tagName)
return tag.Attributes["v"].InnerText;
return null;
}
List<string> result = new List<string>();
void Replace(XmlElement way, string tag)
{
bool uk = tag != "name:ru";
string name = GetTag(way, tag);
if (name == null)
return;
string newName = Regex.Replace(name,
"(?<p1>\\d-й )?(?<p2>" + (uk ? "провулок|вулиця" : "переулок|улица") +
") (?<p3>.*)(?<p4>$)", "${p1}${p3} ${p2}${p4}");
if (name != newName)
{
result.Add(name + " -> " + newName);
SetTag(way, tag, newName);
}
else
result.Insert(0, name + " ->");
}
Program()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(File.ReadAllText("e:\\rda_all.osm"));
foreach (XmlElement way in doc.DocumentElement.SelectNodes("/osm/way"))
{
if (GetTag(way, "highway") != null &&
GetTag(way, "name") != null)
{
Replace(way, "name");
Replace(way, "name:ru");
Replace(way, "name:uk");
}
}
File.WriteAllLines("e:\\result.txt", result);
doc.Save("e:\\rda_fix.osm");
}
static void Main(string[] args)
{
new Program();
}
}
}
Вторая партия:
Круто, спасибо.
Думаю, что большая часть пофикшена, а если что-то и осталось, можно будет руками доделать.