Создание инструмента для карты обработки нажатия мыши

Не знаете, где задать вопрос? Задавайте здесь.
Ответить
lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 30 янв 2017, 14:35

Добрый день
Пишу программу на python с картами qgis. Хочу создать инструмент для карты для обработки нажатия на объект карты. Мне необходима получить объект, создать в этом месте контекстное меню и выбрать там команду именно для этой точки. Нашел в инете вот такие пример, но не могу понять как его применить. [img]

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

class PointTool(QgsMapTool):   
    def __init__(self, canvas):
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas    

    def canvasPressEvent(self, event):
        pass

    def canvasMoveEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)

    def canvasReleaseEvent(self, event):
        #Get the click
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)

    def activate(self):
        pass

    def deactivate(self):
        pass

    def isZoomTool(self):
        return False

    def isTransient(self):
        return False

    def isEditTool(self):
        return True
Вложения
111.png
111.png (170.52 КБ) 7391 просмотр

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 30 янв 2017, 14:42

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

class MainWindow()
    ....
    self.clickTool = PointTool(self.canvas)
    self.clickTool.setAction(self.mpActionIndetity) # элемент с формочки, активирущий инструмент
    self.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.mapClicked())
    ....
    def mapClicked(self):
        """
        Выполняется при выборе инструмента
        :return:
        """
        self.canvas.setMapTool(self.clickTool)
Он падает, когда в вызове self.canvas.setMapTool(self.clickTool) выполняется функция activate() (она пустая) из PointTool

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 31 янв 2017, 14:41

С созданием инструмента разобрался, сделал так, что бы он рисовал точку в том месте, где я тыкнул на карте.
Мне надо, что бы можно было нажимать только на объекты на карте и вызвать именно для них действия (отображать контекстное меню)
Так же было отлично, что бы при наведение на объект на карте он как-то обозначался (например немного увеличивался.
Вложения
11111.png
11111.png (274.61 КБ) 7332 просмотра

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 31 янв 2017, 14:42

квадратики - это то что рисует мой инструмент при нажатие на карту
линия - мои эксперементы с фукциями, она здесь не нужна

Аватара пользователя
Евгений Брусникин
Новоприбывший
Сообщения: 14
Зарегистрирован: 31 май 2014, 14:21
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение Евгений Брусникин » 31 янв 2017, 14:53

lololol писал(а):Мне надо, что бы можно было нажимать только на объекты на карте и вызвать именно для них действия (отображать контекстное меню)
Вам нужно что-бы объекты создавались только уже на существующих объектах в другом слое? Костыльное решение, но все же может помочь: снаппинг к вершинам объектов (просто увеличить прилипание к объектам)

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 31 янв 2017, 15:41

смог отслеживать местоположение мыши и получать ее координаты. Теперь вопрос есть ли стандартная функция для опредения наведена ли мышь на объект или нет? пока вариант реализовать ее самому, получив координаты всех точек и просто проверять попадат ли текущие координаты мыши в некую область рядом с точкой?

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 31 янв 2017, 16:07

Евгений Брусникин писал(а):
lololol писал(а): Вам нужно что-бы объекты создавались только уже на существующих объектах в другом слое? Костыльное решение, но все же может помочь: снаппинг к вершинам объектов (просто увеличить прилипание к объектам)
мне нужно для объекта вызвать меню с действиями.
как это делается, не могли бы подсказать? я в qgis знаю чуть больше, чем 0.0 )))

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 31 янв 2017, 16:08

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

Аватара пользователя
Евгений Брусникин
Новоприбывший
Сообщения: 14
Зарегистрирован: 31 май 2014, 14:21
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение Евгений Брусникин » 31 янв 2017, 16:09

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

%LAYER1%.getFeatures(QgsFeatureRequest().setFilterRect(%LAYER2%.geometry().boundingBox()))
if %LAYER2%.getFeatures.geometry().intersects(%LAYER1%.getFeatures.geometry()):
условие пересечения объектов. Если перескаются индентифицируем по любому столбцу слоя.
не уверен, что реализуемо на лету, но для 2 статичных (не редактируемых) слоев подходит

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 01 фев 2017, 07:14

Евгений Брусникин писал(а): условие пересечения объектов. Если перескаются индентифицируем по любому столбцу слоя.
не уверен, что реализуемо на лету, но для 2 статичных (не редактируемых) слоев подходит
а если я работаю с одним слоем? точнее у меня будет один слой с точками и несколько прочих слоев для создание фона.
не совсем сообразил, ведь в этом примере нет точки координат мыши. Или я что то не понимаю или как с его помощью определять, что текушее положение мыши попадает в некую область вокруг какой-либо точки?

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 01 фев 2017, 13:44

нашел способ через создание индексов. Вроде мне подходит, но не доконца знаю что и как

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

# создать индекс
index = QgsSpatialIndex()
# проиндексировать все элементы слоя
iter = layer.getFeatures()
for feature in iter:
    self.index.insertFeature(feature)

# возвращает массив идентификаторов пяти, ближайших к заданной точке, объектов
nearest = index.nearestNeighbor(QgsPoint(25.4, 12.7), 5)
# nearest = [283L, 329L, 371L, 737L, 286L]

# возвращает массив идентификаторов объектов, пересекающихся с заданным прямоугольником
intersect = index.intersects(QgsRectangle(22.5, 15.3, 23.1, 17.2))
# intersect  = [770L, 233L, 489L, 771L, 455L]
https://gis-lab.info/docs/qgis/cookbook/vector.html - пример отсюда

вопрос, что это за индексы и что мне с ними теперь делать?))

lololol
Участник
Сообщения: 55
Зарегистрирован: 11 фев 2016, 23:52
Репутация: 0

Re: Создание инструмента для карты обработки нажатия мыши

Сообщение lololol » 01 фев 2017, 13:54

Нашел еще пример, в котором находят соседей для каждого полигона и суммируют население соседних стран
http://www.qgistutorials.com/ru/docs/fi ... ygons.html

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

from qgis.utils import iface
from PyQt4.QtCore import QVariant

# Replace the values below with values from your layer.
# For example, if your identifier field is called 'XYZ', then change the line
# below to _NAME_FIELD = 'XYZ'
_NAME_FIELD = 'NAME'
# Replace the value below with the field name that you want to sum up.
# For example, if the # field that you want to sum up is called 'VALUES', then
# change the line below to _SUM_FIELD = 'VALUES'
_SUM_FIELD = 'POP_EST'

# Names of the new fields to be added to the layer
_NEW_NEIGHBORS_FIELD = 'NEIGHBORS'
_NEW_SUM_FIELD = 'SUM'

layer = iface.activeLayer()

# Create 2 new fields in the layer that will hold the list of neighbors and sum
# of the chosen field.
layer.startEditing()
layer.dataProvider().addAttributes(
        [QgsField(_NEW_NEIGHBORS_FIELD, QVariant.String),
         QgsField(_NEW_SUM_FIELD, QVariant.Int)])
layer.updateFields()
# Create a dictionary of all features
feature_dict = {f.id(): f for f in layer.getFeatures()}

# Build a spatial index
index = QgsSpatialIndex()
for f in feature_dict.values():
    index.insertFeature(f)

# Loop through all features and find features that touch each feature
for f in feature_dict.values():
    print 'Working on %s' % f[_NAME_FIELD]
    geom = f.geometry()
    # Find all features that intersect the bounding box of the current feature.
    # We use spatial index to find the features intersecting the bounding box
    # of the current feature. This will narrow down the features that we need
    # to check neighboring features.
    intersecting_ids = index.intersects(geom.boundingBox())
    # Initalize neighbors list and sum
    neighbors = []
    neighbors_sum = 0
    for intersecting_id in intersecting_ids:
        # Look up the feature from the dictionary
        intersecting_f = feature_dict[intersecting_id]

        # For our purpose we consider a feature as 'neighbor' if it touches or
        # intersects a feature. We use the 'disjoint' predicate to satisfy
        # these conditions. So if a feature is not disjoint, it is a neighbor.
        if (f != intersecting_f and
            not intersecting_f.geometry().disjoint(geom)):
            neighbors.append(intersecting_f[_NAME_FIELD])
            neighbors_sum += intersecting_f[_SUM_FIELD]
    f[_NEW_NEIGHBORS_FIELD] = ','.join(neighbors)
    f[_NEW_SUM_FIELD] = neighbors_sum
    # Update the layer with new attribute values.
    layer.updateFeature(f)

layer.commitChanges()
print 'Processing complete.'

Ответить

Вернуться в «Я новичок!»

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

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