Обновление карты и полигоны с "дыркой"

Вопросы по свободной ГИС QGIS. Сообщения об ошибках, предложения по улучшению, локализация.
Ответить
Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Обновление карты и полигоны с "дыркой"

Сообщение Voltron » 21 авг 2008, 09:28

Пишу Python-плагин для Qgis (загрузка данных из файлов обмена спец. формата), почти все уже готово но вылезло две проблемки:
  1. когда происходит вставка нового объекта в слой (полигональный шейп-файл), то на карте новый объект не появляется и в таблице атрибутов слоя новой записи тоже нет. А вот если удалить слой из проекта и добавить заново - ранее вставленные объекты становятся видны. Пробовал вызывать после вставки MapCanvas.refresh(), но это тоже не помогает. Вот код вставки:

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

    # lstCoords - массив поворотных точек
    # attr1..attr3 - атрибуты объекта
    mc = self.iface.getMapCanvas()
    vLayer = QgsVectorLayer('D:/test', 'test', 'ogr')
    fet = QgsFeature()
    fet.setGeometry(QgsGeometry.fromPolygon([lstCoords]))
    fet.addAttribute(0, QVariant(attr0))
    fet.addAttribute(1, QVariant(attr1))
    fet.addAttribute(2, QVariant(attr2))
    fet.addAttribute(3, QVariant(attr3))
    vLayer.startEditing()
    if vLayer.addFeature(fet, True):
            vLayer.commitChanges()
            vLayer.setModified()
            vLayer.updateExtents()
            mc.refresh() 
    
    В чем может быть проблема? Возможно, что-то делаю не так?
  2. иногда встречаются полигоны с внутренним контуром (с "дырками"). Координаты поворотных точек идут единым массивом, т.е. я заранее не знаю есть ли в полигоне дырка или нет. Как корректно создавать такие полигоны?

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9128
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 747
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: Обновление карты и полигоны с "дыркой"

Сообщение Максим Дубинин » 21 авг 2008, 09:56

ни того ни другого сам не делал, но пара есть соображений:

1. может попробовать после создания полностью пересоздать LayerSet? setLayerSet и т.д.

2. я бы посмотрел что возвращает инструмент для создания подобных полигонов самого QGIS, он правда на c++, но думаю должно быть понятно.
пристегивайтесь, турбулентность прямо по курсу

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Обновление карты и полигоны с "дыркой"

Сообщение Voltron » 21 авг 2008, 15:03

Спасибо за ответ. К сожалению, игры с LayerSet'ом положительного результата не дали, так что вопрос пока остается открытым. Как вариант, можно удалять слой из проекта после импорта обменного файла, а потом подключать его обратно. Но это некошерно, хочется сделать красиво и правильно.
Полигоны с "дырками" пока не столь важны (но за совет тоже спасибо, качну исходники и гляну), главное реализовать обновление.

serge
Интересующийся
Сообщения: 15
Зарегистрирован: 14 окт 2007, 14:26
Репутация: 0

Re: Обновление карты и полигоны с "дыркой"

Сообщение serge » 29 авг 2008, 02:42

Здравствуйте, возможно первую проблему решит
вызов

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

self.iface.getMapCanvas().setCurrentLayer(vLayer) 
после addFeature с последующим обновлением MapCanvas

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

vLayer.updateFeatureCount()

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Обновление карты и полигоны с "дыркой"

Сообщение Voltron » 29 авг 2008, 09:23

Попробовал применить ваши рекомендации - без результата :-(.
Копание в документации по API тоже пока результатов не дает. Подозреваю, что нужно как-то задействовать сигналы и слоты, но с какой стороны подступиться не знаю.

serge
Интересующийся
Сообщения: 15
Зарегистрирован: 14 окт 2007, 14:26
Репутация: 0

Re: Обновление карты и полигоны с "дыркой"

Сообщение serge » 29 авг 2008, 10:17

У меня следующий код работает на ура (C++):

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

mQGisIface->getMapCanvas()->setCurrentLayer(layer);
layer->removeSelection(false);

QgsFeature feature = QgsFeature();
feature.setGeometry(QgsGeometry::fromRect(rect));

layer->startEditing();

if (layer->addFeature(feature, true)) {
	mQGisIface->getMapCanvas()->refresh();
}
Какая у вас версия qgis?

serge
Интересующийся
Сообщения: 15
Зарегистрирован: 14 окт 2007, 14:26
Репутация: 0

Re: Обновление карты и полигоны с "дыркой"

Сообщение serge » 29 авг 2008, 10:26

По поводу создания полигонов с "дырками", у класса QgsGeometry есть метод addRing...

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Обновление карты и полигоны с "дыркой"

Сообщение Voltron » 29 авг 2008, 14:39

Пробовал на нескольких версиях: 0.9.1 (от 18.12.2007), 0.9.2rc1 (от 05.02.2008) и 0.10 и на разных компах (WinXP Pro SP1 и SP2). Везде одна и та же картина - обновления нет. Не исключено, что это просто глюк в реализации взаимодействия с Python-плагинами под Windows, т.к. вызова MapCanvas.refresh(), по идее, должно быть достаточно. Качаю 0.11, проверю еще там.
Может, я не совсем корректно сформулировал второй вопрос. Про метод addRing в курсе :-). Это работает, когда известны отдельно координаты внешнего контура и колец. У меня же есть просто массив точек без деления на внешний и внутренние контура. Вот пример:

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

N, X, Y
2, 545.50, 519.15,
3, 472.25, 524.65,
4, 473.75, 444.06,
8, 499.25, 473.59,
7, 500.75, 501.88,
6, 526.25, 498.12,
5, 525.50, 473.09,
8, 499.25, 473.59,
4, 473.75, 444.06,
1, 545.00, 444.81
Здесь есть внешний контур (точки 1-4) и внутренний (5-8). Интересует метод, не требующий раздельного задания координат внешнего и внутреннего контура (если он существует). Ну а если нет... Что ж, чуть хуже будет выглядеть картинка - полигоны построенные по полному массиву получаются с "перемычками".

serge
Интересующийся
Сообщения: 15
Зарегистрирован: 14 окт 2007, 14:26
Репутация: 0

Re: Обновление карты и полигоны с "дыркой"

Сообщение serge » 29 авг 2008, 15:17

По первому вопросу, я пробовал на 0.11

serge
Интересующийся
Сообщения: 15
Зарегистрирован: 14 окт 2007, 14:26
Репутация: 0

Re: Обновление карты и полигоны с "дыркой"

Сообщение serge » 29 авг 2008, 15:28

Что касается второго, то это вы конечно преувеличили возможности qgis. Интересно как он должен за вас выделять контура, откуда он знает о их количестве и пр. Если вы точно уверены, что некоторый набор точек состоит из 2-х контуров, то из него можно выделить соответствующие два набора точек и передать их уже qgis - один как внешний, а второй как внутренний контура. Такое разделение я бы сделал т.о.: обвел выпуклую оболочку вокруг общего множества (проблема, если "настоящий" полигон не выпуклый) - контур полигона, далее через оставшиеся вершины провел точно такую же оболочку (гарантированно внутри внешней) - "дырка" полигона. А теперь представте каким образом с поставленной задачей должен был справиться qgis)

Voltron
Гуру
Сообщения: 2627
Зарегистрирован: 29 мар 2007, 14:12
Репутация: 34
Откуда: Ukraine

Re: Обновление карты и полигоны с "дыркой"

Сообщение Voltron » 29 авг 2008, 15:50

Ну вот, выкачал 0.11. Нет слов, ситуация один в один - не обновляется хоть ты тресни. Буду копать дальше.
С полигонами ситуация такая. Пару лет назад для ArcView 3.2 мной писался скрипт импорта файлов этого же формата... Представьте себе мое удивление, когда еще при тестировании все полигоны (с "дырками" и без) отображались абсолютно корректно. Причем никаких специальных шагов для этого с моей стороны не предпринималось, был просто вызов

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

plg=Polygon.Make({lstCoords})
и сохранение полученного полигона в Shape-поле атрибутивной таблицы (работа шла с шейп-файлами). Чуть позже пришлось столкнуться с ArcMap 9.1, авенюшный скрипт переписали на VBA. В результате, при сохранении данных с слой SDE полигоны отображались корректно, а если использовать шейп-файлов - появлялась "перемычка". Вот вам причина появления второго вопроса.
Т.к. наличие "перемычек" влияет только на внешний вид (площадь получается правильной), второй вопрос можно считать закрытым.

Ответить

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

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

Сейчас этот форум просматривают: Amazon [Bot] и 5 гостей