1 Востаннє редагувалося P.Y. (11.04.2016 15:26:37)

Тема: Робота з SVG

Задача: існує svg-файл (що містить географічну карту світу в еквіректангулярній проекції — тобто, x та у відповідають широті й довготі), який треба перетворити в іншу проекцію (скажімо, карти материкової й океанічної півкуль, чи ще якусь). Всі елементи зображення задаються тегами path. 
Перетворення координат задається функцією.

мій індусокод на поточній стадії розробки
import re


def svgtransform(inf, outf, transform):
    '''
    Замінити всі координати в svg path, використовуючи
    ф-ю transform(old_x, old_y)->(new_x, new_y)
    Всі відносні координати конвертуються в абсолютні.
    
    TODO: transform=translate....
    '''
    lastxy=[0,0]
    def re_transform(m):
        c, x, y=m.groups()
        # if relative, convert to absolute:
        if 'a'<c<'z':
            x+=lastxy[0]
            y+=lastxy[1]
            c=c.upper()
        new_x, new_y = transform(x, y)
        res="%s %s,%s"%(c, new_x, new_y)
        lastxy[:]=(x,y)        
        return res
    if isinstance(inf, str):
        inf=open(inf)
    if isinstance(outf, str):
        outf=open(outf, 'w')
    in_quot=False
    for s in inf:
        ss=re.split(r'(^| d=")([^"]*)' if in_quot else r'( d=")([^"]*)', s)
        for i in range(2, len(ss), 3):
            lastxy[:]=(0,0)
            ss[i]=re.sub(r'([a-zA-Z])\s*([0-9.e\-+]+)\s*([0-9.e\-+]+)', re_transform, ss[i])
        in_quot=not ss[-1]
        outf.write(''.join(ss))
    outf.close()
    inf.close()

В чому складність: по-перше, окрім відносних координат в svg path, зміщення координат також може задаватися атрибутом transform — його теж треба позбутися, а всі координати перетворити на абсолютні. По-друге, для багатьох проекцій карту треба кроїти на частини (тобто, лінія розрізу може проходити через окремий path-об'єкт).
Питання: чи існують пітонівські бібліотеки, призначені для подібних маніпуляцій з svg?

Подякували: 0xDADA11C7, leofun012

2

Re: Робота з SVG

Може оце допоможе
http://lmgtfy.com/?q=python+svg

А так-то це питання для дуже вузького кола людей, і дуже сумніваюся, що на цьому форумі є ще хтось, хто бавиться із svg

Подякували: leofun011

3

Re: Робота з SVG

Дякую за невдалу спробу допомогти, але я не маю звички щось питати, попередньо не прогугливши тему, і вважаю погану манерою давати відповідь там, де відповідь гугла буде більш інформативною.

У даному випадку, потрібна фільтрація результатів, виданих гуглом, з точки зору придатності їх для вирішення даної задачі (тобто, всі svg-to-xxx-converters-for-python i python-logo-svg можна відкинути). Особливо цікавить думка тих, хто справді мав справу з svg.

4 Востаннє редагувалося leofun01 (11.04.2016 19:48:52)

Re: Робота з SVG

P.Y. написав:

по-перше, окрім відносних координат в svg path, зміщення координат також може задаватися атрибутом transform — його теж треба позбутися, а всі координати перетворити на абсолютні.

Перетворювати всі координати в абсолютні я б не радив, краще трохи помучитися з програмою, але зробити правильно.
Path в SVG задається послідовністю точок. Path може бути відкритий, або замкнутий, і я так розумію, у Вас всі - замкнуті. Вам потрібно розглядати кожну послідовну пару точок і перевіряти чи перетинає межу утворена частина шляху (з урахуванням transform). І якщо перетинає, то розбивати весь шлях на кілька частин, при чому не факт, що їх буде 2, може вийти і більше, після цього потрібно замкнути кожну частину. Також будьте готові до того, що можливо доведеться освоїти криві Безьє в SVG.

P.Y. написав:

чи існують пітонівські бібліотеки, призначені для подібних маніпуляцій з svg?

За пітонівські бібліотеки для SVG нічого не знаю.

Master_Sergius написав:

... дуже сумніваюся, що на цьому форумі є ще хтось, хто бавиться із svg

Є, і не тільки бавиться.

Подякували: 0xDADA11C7, P.Y.2

5

Re: Робота з SVG

Перетворювати всі координати в абсолютні я б не радив

У даному випадку, для правильного виконання потрібні саме абсолютні. Хоча, при бажанні, абсолютні координати можна перетворити на відносні після побудови проекції.

Вам потрібно розглядати кожну послідовну пару точок і перевіряти чи перетинає межу утворена частина шляху (з урахуванням transform). І якщо перетинає, то розбивати весь шлях на кілька частин, при чому не факт, що їх буде 2, може вийти і більше, після цього потрібно замкнути кожну частину. Також будьте готові до того, що можливо доведеться освоїти криві Безьє в SVG.

Можна й так, але не хотілось би конструювати велосипед, якщо існують готові рішення. Зокрема, розглядаю варіант використати для цього Inkscape в безguiшному режимі (хоча пітонівський модуль з аналогічними можливостями був би кращим варіантом).

Подякували: leofun011