Округлить координаты объектов

Вопросы по свободной ГИС QGIS. Сообщения об ошибках, предложения по улучшению, локализация.
Аватара пользователя
t[0]p
Участник
Сообщения: 93
Зарегистрирован: 15 ноя 2014, 14:35
Репутация: 7
Откуда: Томск

Округлить координаты объектов

Сообщение t[0]p » 14 дек 2017, 05:24

Здравствуйте.
Есть shp'ы. Хочу округлять координаты узлов объектов до 7 знака после запятой (потому что часто знаков после запятой 14-15). Ни чего ненагуглилось простого. Написал скрипт на pythone в котором получаю координаты объектов, открытого в QGIS слоя, с помощью функции round() округляю их, и перезаписываю геометрию:

Код: Выделить всё

from qgis.PyQt.QtCore import *

layer = iface.activeLayer()
for i in layer.getFeatures():
    geom = i.geometry()
    list = geom.asPolygon()
    poly = []
    for polygone in list:
        for point in polygone:
            lon = point[0]
            lat = point[1]
            poly.append(QgsPoint(round(lon, 7), round(lat, 7)))
        layer.dataProvider().changeGeometryValues({i.id(): QgsGeometry.fromPolygon([poly])})
        crs = layer.crs()
        crs.createFromId(4326)
        layer.setCrs(crs)
        QgsMapLayerRegistry.instance().addMapLayer(layer)
Всё работает, но это слишком долго для shp'ов с овер 200к объектов, да и для полигонов с inner ring'ами нужно допилить мой цикл.
Отсюда вопрос: Не покидает ощущения того, что я всё усложнил. Неужто округлить координаты в shp'е нельзя каким то простым ("кнопочным") образом? Возможно какая то функция есть в pyqgis'е которая это делает без перезаписывания геометрии...
Последний раз редактировалось t[0]p 18 дек 2017, 14:30, всего редактировалось 1 раз.

Аватара пользователя
Игорь Белов
Гуру
Сообщения: 2229
Зарегистрирован: 04 янв 2011, 22:00
Репутация: 1501
Откуда: Казань

Re: Округлить координаты объектов

Сообщение Игорь Белов » 14 дек 2017, 08:04

Координаты в шейпах хранятся в бинарном представлении, так что «округление» не уменьшит размер файла и не ускорит работу.

Округление имеет смысл при экспорте в форматы, где геометрия хранится в текстовом виде, но тогда ни к чему переживать по поводу «слишком долго для shp'ов с овер 200к объектов».
The purpose of computing is insight, not numbers

Ariki
Гуру
Сообщения: 731
Зарегистрирован: 12 янв 2011, 22:40
Репутация: 304
Ваше звание:

Re: Округлить координаты объектов

Сообщение Ariki » 14 дек 2017, 15:45

Если говорить о коде, то последние 4 строчки просятся, чтобы их вынесли из цикла. Да и пятая с конца тоже не на своём уровне отступа. И не используйте changeGeometryValues(): вы всё равно итерируетесь по всем геометриям, так что updateFeature() тут должно работать быстрее (попробовал на своём наборе данных - выигрыш в 4 раза). Ещё, может быть, удастся немного выиграть в скорости, если вы будете модифицировать список вершин на месте, а не выделять память под новый, добавляя вершины по одной.

Что касается смысла в самом округлении - Игорь Белов прав, выигрыша в скорости вы не получите. Если же стоит задача добиться топологической корректности, выровняв вершины по сетке, то тут округление - не лучший способ: в некоторых случаях соседние вершины могут округлиться в разные стороны и стать ещё дальше друг от друга. Не говоря уже о том, что округление чисел с плавающей точкой до определённого числа десятичных разрядов - вещь достаточно условная.

Кстати, вашу задачу можно выполнить в PostGIS с помощью функции ST_SnapToGrid().

Аватара пользователя
t[0]p
Участник
Сообщения: 93
Зарегистрирован: 15 ноя 2014, 14:35
Репутация: 7
Откуда: Томск

Re: Округлить координаты объектов

Сообщение t[0]p » 15 дек 2017, 12:17

Ariki писал(а):
14 дек 2017, 15:45
Что касается смысла в самом округлении - Игорь Белов прав
Конечно прав. И округляю именно для того что бы перенести в БД в формат WKT.
Ariki писал(а):
14 дек 2017, 15:45
Ещё, может быть, удастся немного выиграть в скорости, если вы будете модифицировать список вершин на месте, а не выделять память под новый, добавляя вершины по одной.
Собственно когда тему создавал - надеялся на то, что есть метод подобный:
Ariki писал(а):
14 дек 2017, 15:45
updateFeature()
который позволит обновлять мне геометрию не перезаписывая её заново, как сейчас происходит в моём цикле. Гугленье не нашло мне эту функцию. Пойду учиться пользоваться updateFeature().

P.S. По поводу последних 5 строчек - глупость с моей стороны, согласен. Но уже было поправлено.
Спасибо за внимание. Думаю, что Вы ответили на мой вопрос...
Последний раз редактировалось t[0]p 15 дек 2017, 12:24, всего редактировалось 1 раз.

trir
Гуру
Сообщения: 5286
Зарегистрирован: 09 апр 2010, 19:30
Репутация: 1015
Ваше звание: просто мимо прохожу
Откуда: Ё-бург

Re: Округлить координаты объектов

Сообщение trir » 15 дек 2017, 12:21

И округляю именно для того что бы перенести в БД в формат WKT.
так в БД она тоже в бинарном виде хранится

Аватара пользователя
t[0]p
Участник
Сообщения: 93
Зарегистрирован: 15 ноя 2014, 14:35
Репутация: 7
Откуда: Томск

Re: Округлить координаты объектов

Сообщение t[0]p » 15 дек 2017, 12:25

trir писал(а):
15 дек 2017, 12:21
так в БД она тоже в бинарном виде хранится
Неа

trir
Гуру
Сообщения: 5286
Зарегистрирован: 09 апр 2010, 19:30
Репутация: 1015
Ваше звание: просто мимо прохожу
Откуда: Ё-бург

Re: Округлить координаты объектов

Сообщение trir » 15 дек 2017, 12:26

Неа
да и обычно даже не в wkb, какая БД?

Аватара пользователя
t[0]p
Участник
Сообщения: 93
Зарегистрирован: 15 ноя 2014, 14:35
Репутация: 7
Откуда: Томск

Re: Округлить координаты объектов

Сообщение t[0]p » 15 дек 2017, 12:30

trir писал(а):
15 дек 2017, 12:26
да, какая БД?
хм...
БД - MS SQL. Колонка: geometry varchar(max). Ну т.е. строчка.

П.С. Да-да, я знаю что есть тип данных geometry/geography =) так нада ...

trir
Гуру
Сообщения: 5286
Зарегистрирован: 09 апр 2010, 19:30
Репутация: 1015
Ваше звание: просто мимо прохожу
Откуда: Ё-бург

Re: Округлить координаты объектов

Сообщение trir » 15 дек 2017, 12:35

facepalm
ЗАЧЕМ???

Ariki
Гуру
Сообщения: 731
Зарегистрирован: 12 янв 2011, 22:40
Репутация: 304
Ваше звание:

Re: Округлить координаты объектов

Сообщение Ariki » 16 дек 2017, 01:33

Если пользуетесь MSSQL, то, может, вот это пригодится:
https://spatialdbadvisor.com/sql_server ... try-object

Аватара пользователя
t[0]p
Участник
Сообщения: 93
Зарегистрирован: 15 ноя 2014, 14:35
Репутация: 7
Откуда: Томск

Re: Округлить координаты объектов

Сообщение t[0]p » 18 дек 2017, 12:32

Авось кому пригодиться. Вот что должно было получится:

Код: Выделить всё

from qgis.PyQt.QtCore import *

layer = iface.activeLayer()
for i in layer.getFeatures():
    geom = i.geometry()
    list = geom.asPolygon()
    print(i.id())
    for polygone in list:
        for point in polygone:
            point.setX(round(point.x(), 7))
            point.setY(round(point.y(), 7)) 
    layer.dataProvider().changeGeometryValues({i.id(): QgsGeometry.fromPolygon(list)})
crs = layer.crs()
crs.createFromId(4326)
layer.setCrs(crs)
QgsMapLayerRegistry.instance().addMapLayer(layer)
Что бы редактировать существующий полигон, и не создавать свой - есть методы setX/setY, которые позволяют назначать координаты точек.
Ariki писал(а):
14 дек 2017, 15:45
не используйте changeGeometryValues()
Как показала практика - не получится не использовать. Метод updateFeature() с геометрию не обновляет.
Ariki писал(а):
14 дек 2017, 15:45
модифицировать список вершин на месте
насколько я понял, в QGIS'е с использованием python нельзя (На картинке указана причина).

Поправьте пожалуйста, если что то
Вложения
123.PNG
пруф
123.PNG (20.55 КБ) 9768 просмотров

Ariki
Гуру
Сообщения: 731
Зарегистрирован: 12 янв 2011, 22:40
Репутация: 304
Ваше звание:

Re: Округлить координаты объектов

Сообщение Ariki » 18 дек 2017, 14:04

А если так?

Код: Выделить всё

from qgis.core import edit, QgsGeometry
from qgis.PyQt.QtCore import *

DECIMAL_PLACES = 7

layer = iface.activeLayer()
with edit(layer):
    for feature in layer.getFeatures():
        geom = feature.geometry()
        polygon = geom.asPolygon()
        for ring in polygon:
            for point in ring:
                point.setX(round(point.x(), DECIMAL_PLACES))
                point.setY(round(point.y(), DECIMAL_PLACES))
        new_geom = QgsGeometry.fromPolygon(polygon)
        feature.setGeometry(new_geom)
        layer.updateFeature(feature)
        
crs = layer.crs()
crs.createFromId(4326)
layer.setCrs(crs)

print('Done')

Аватара пользователя
t[0]p
Участник
Сообщения: 93
Зарегистрирован: 15 ноя 2014, 14:35
Репутация: 7
Откуда: Томск

Re: Округлить координаты объектов

Сообщение t[0]p » 18 дек 2017, 14:29

Ariki писал(а):
18 дек 2017, 14:04
А если так?
Прекрасно работает... Понял свою ошибку.
Спасибо за внимание!

Аватара пользователя
antonv
Активный участник
Сообщения: 229
Зарегистрирован: 29 ноя 2016, 10:44
Репутация: 114
Откуда: Санкт-Петербург

Re: Округлить координаты объектов

Сообщение antonv » 05 янв 2018, 17:51

t[0 писал(а):p post_id=158594 time=1513218274 user_id=17314]Ни чего ненагуглилось простого.

В QGIS при сохранении векторного слоя в формате geojson можно задать параметр COORDINATE_PRECISION, влияющий именно на количество знаков после запятой в координатах. Можно попробовать сохранить шейп в geojson (правда, при 200к объектов текстовый файл geojson может неприлично много весить, но это сильно зависит от геометрии), а затем снова сохранить его как шейп.
Последний раз редактировалось antonv 04 фев 2018, 14:51, всего редактировалось 1 раз.

Mikhael
Новоприбывший
Сообщения: 1
Зарегистрирован: 05 янв 2018, 22:45
Репутация: 0
Ваше звание: Студент
Откуда: Горно-Алтайск

Re: Округлить координаты объектов

Сообщение Mikhael » 05 янв 2018, 22:55

Здравствуйте, не могли бы вы мне помочь в одном вопросе, а именно : я установил Qgis(Las palmas) . В нем у меня было задание для работы с изолиниями. Так вот мне дали файл республики Алтай(карта) в университете , и в кратце сказал преподаватель как начать работу. Но сколько я не пытался программа выдает ошибку. В чем же дело я не могу понять. Может вы посоветуете мне выход. И есть ли у вас на сайте похожие работы по построению изолиний , где бы я мог восполнить свои пробелы в знаниях программы!?
Заранее спасибо.

Ответить

Вернуться в «QGIS»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя