Пропозиція - природній порядок слів у назвах вулиць

Попробую сделать.

upd. Сделал

Вот в этом месте несколько улиц не пофиксились
https://www.openstreetmap.org/way/428721212#map=16/48.9285/34.4878

На http://nadoloni.com/editor/streets є функція Autofix, вона вміє виправляти порядок слів

Хм. Я выбирал улицы с последней правкой от Царичанська РДА.
Есть идеи как довыбрать оставшиеся?
Не хотелось бы по всему квадрату запускать замены - мало ли что можно сломать.

Найти все, где их правка была предпоследней, посмотреть, что выйдет и так далее.

Я делал запрос через Overpass:
http://overpass-turbo.eu/s/hvu
В описании языка нашел только вот это:
http://wiki.openstreetmap.org/wiki/RU:Overpass_API/Overpass_QL#By_user_.28user.2C_uid.29
Похоже, запросов для предпоследней правки нет :frowning:

Остаётся разве что качать все ченжсеты юзера.
Но для этого у меня пока что инструментов нет.

Вторая партия:
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();
        }
    }
}

Круто, спасибо.
Думаю, что большая часть пофикшена, а если что-то и осталось, можно будет руками доделать.

Осталось “квартал Слави”.
https://www.openstreetmap.org/#map=18/48.94389/34.48882&layers=H