Страница 1 из 2
Округлить координаты объектов
Добавлено: 14 дек 2017, 05:24
t[0]p
Здравствуйте.
Есть 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'е которая это делает без перезаписывания геометрии...
Re: Округлить координаты объектов
Добавлено: 14 дек 2017, 08:04
Игорь Белов
Координаты в шейпах хранятся в
бинарном представлении, так что «округление» не уменьшит размер файла и не ускорит работу.
Округление имеет смысл при экспорте в форматы, где геометрия хранится в текстовом виде, но тогда ни к чему переживать по поводу «слишком долго для shp'ов с овер 200к объектов».
Re: Округлить координаты объектов
Добавлено: 14 дек 2017, 15:45
Ariki
Если говорить о коде, то последние 4 строчки просятся, чтобы их вынесли из цикла. Да и пятая с конца тоже не на своём уровне отступа. И не используйте changeGeometryValues(): вы всё равно итерируетесь по всем геометриям, так что updateFeature() тут должно работать быстрее (попробовал на своём наборе данных - выигрыш в 4 раза). Ещё, может быть, удастся немного выиграть в скорости, если вы будете модифицировать список вершин на месте, а не выделять память под новый, добавляя вершины по одной.
Что касается смысла в самом округлении - Игорь Белов прав, выигрыша в скорости вы не получите. Если же стоит задача добиться топологической корректности, выровняв вершины по сетке, то тут округление - не лучший способ: в некоторых случаях соседние вершины могут округлиться в разные стороны и стать ещё дальше друг от друга. Не говоря уже о том, что округление чисел с плавающей точкой до определённого числа десятичных разрядов - вещь достаточно условная.
Кстати, вашу задачу можно выполнить в PostGIS с помощью функции ST_SnapToGrid().
Re: Округлить координаты объектов
Добавлено: 15 дек 2017, 12:17
t[0]p
Ariki писал(а): ↑14 дек 2017, 15:45
Что касается смысла в самом округлении - Игорь Белов прав
Конечно прав. И округляю именно для того что бы перенести в БД в формат WKT.
Ariki писал(а): ↑14 дек 2017, 15:45
Ещё, может быть, удастся немного выиграть в скорости, если вы будете модифицировать список вершин на месте, а не выделять память под новый, добавляя вершины по одной.
Собственно когда тему создавал - надеялся на то, что есть метод подобный:
Ariki писал(а): ↑14 дек 2017, 15:45
updateFeature()
который позволит обновлять мне геометрию не перезаписывая её заново, как сейчас происходит в моём цикле. Гугленье не нашло мне эту функцию. Пойду учиться пользоваться updateFeature().
P.S. По поводу последних 5 строчек - глупость с моей стороны, согласен. Но уже было поправлено.
Спасибо за внимание. Думаю, что Вы ответили на мой вопрос...
Re: Округлить координаты объектов
Добавлено: 15 дек 2017, 12:21
trir
И округляю именно для того что бы перенести в БД в формат WKT.
так в БД она тоже в бинарном виде хранится
Re: Округлить координаты объектов
Добавлено: 15 дек 2017, 12:25
t[0]p
trir писал(а): ↑15 дек 2017, 12:21
так в БД она тоже в бинарном виде хранится
Неа
Re: Округлить координаты объектов
Добавлено: 15 дек 2017, 12:26
trir
Неа
да и обычно даже не в wkb, какая БД?
Re: Округлить координаты объектов
Добавлено: 15 дек 2017, 12:30
t[0]p
trir писал(а): ↑15 дек 2017, 12:26
да, какая БД?
хм...
БД - MS SQL. Колонка: geometry varchar(max). Ну т.е. строчка.
П.С. Да-да, я знаю что есть тип данных geometry/geography =) так нада ...
Re: Округлить координаты объектов
Добавлено: 15 дек 2017, 12:35
trir
facepalm
ЗАЧЕМ???
Re: Округлить координаты объектов
Добавлено: 16 дек 2017, 01:33
Ariki
Если пользуетесь MSSQL, то, может, вот это пригодится:
https://spatialdbadvisor.com/sql_server ... try-object
Re: Округлить координаты объектов
Добавлено: 18 дек 2017, 12:32
t[0]p
Авось кому пригодиться. Вот что должно было получится:
Код: Выделить всё
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 нельзя (На картинке указана причина).
Поправьте пожалуйста, если что то
Re: Округлить координаты объектов
Добавлено: 18 дек 2017, 14:04
Ariki
А если так?
Код: Выделить всё
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')
Re: Округлить координаты объектов
Добавлено: 18 дек 2017, 14:29
t[0]p
Ariki писал(а): ↑18 дек 2017, 14:04
А если так?
Прекрасно работает... Понял свою ошибку.
Спасибо за внимание!
Re: Округлить координаты объектов
Добавлено: 05 янв 2018, 17:51
antonv
t[0 писал(а):p post_id=158594 time=1513218274 user_id=17314]Ни чего ненагуглилось простого.
В QGIS при сохранении векторного слоя в формате geojson можно задать параметр COORDINATE_PRECISION, влияющий именно на количество знаков после запятой в координатах. Можно попробовать сохранить шейп в geojson (правда, при 200к объектов текстовый файл geojson может неприлично много весить, но это сильно зависит от геометрии), а затем снова сохранить его как шейп.
Re: Округлить координаты объектов
Добавлено: 05 янв 2018, 22:55
Mikhael
Здравствуйте, не могли бы вы мне помочь в одном вопросе, а именно : я установил Qgis(Las palmas) . В нем у меня было задание для работы с изолиниями. Так вот мне дали файл республики Алтай(карта) в университете , и в кратце сказал преподаватель как начать работу. Но сколько я не пытался программа выдает ошибку. В чем же дело я не могу понять. Может вы посоветуете мне выход. И есть ли у вас на сайте похожие работы по построению изолиний , где бы я мог восполнить свои пробелы в знаниях программы!?
Заранее спасибо.