Не знаете, где задать вопрос? Задавайте здесь.
-
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 (170.52 КБ) 7391 просмотр
-
lololol
- Участник
- Сообщения: 55
- Зарегистрирован: 11 фев 2016, 23:52
- Репутация: 0
Сообщение
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
Сообщение
lololol » 31 янв 2017, 14:41
С созданием инструмента разобрался, сделал так, что бы он рисовал точку в том месте, где я тыкнул на карте.
Мне надо, что бы можно было нажимать только на объекты на карте и вызвать именно для них действия (отображать контекстное меню)
Так же было отлично, что бы при наведение на объект на карте он как-то обозначался (например немного увеличивался.
-
Вложения
-
- 11111.png (274.61 КБ) 7332 просмотра
-
lololol
- Участник
- Сообщения: 55
- Зарегистрирован: 11 фев 2016, 23:52
- Репутация: 0
Сообщение
lololol » 31 янв 2017, 14:42
квадратики - это то что рисует мой инструмент при нажатие на карту
линия - мои эксперементы с фукциями, она здесь не нужна
-
Евгений Брусникин
- Новоприбывший
- Сообщения: 14
- Зарегистрирован: 31 май 2014, 14:21
- Репутация: 0
Сообщение
Евгений Брусникин » 31 янв 2017, 14:53
lololol писал(а):Мне надо, что бы можно было нажимать только на объекты на карте и вызвать именно для них действия (отображать контекстное меню)
Вам нужно что-бы объекты создавались только уже на существующих объектах в другом слое? Костыльное решение, но все же может помочь: снаппинг к вершинам объектов (просто увеличить прилипание к объектам)
-
lololol
- Участник
- Сообщения: 55
- Зарегистрирован: 11 фев 2016, 23:52
- Репутация: 0
Сообщение
lololol » 31 янв 2017, 15:41
смог отслеживать местоположение мыши и получать ее координаты. Теперь вопрос есть ли стандартная функция для опредения наведена ли мышь на объект или нет? пока вариант реализовать ее самому, получив координаты всех точек и просто проверять попадат ли текущие координаты мыши в некую область рядом с точкой?
-
lololol
- Участник
- Сообщения: 55
- Зарегистрирован: 11 фев 2016, 23:52
- Репутация: 0
Сообщение
lololol » 31 янв 2017, 16:07
Евгений Брусникин писал(а):lololol писал(а):
Вам нужно что-бы объекты создавались только уже на существующих объектах в другом слое? Костыльное решение, но все же может помочь: снаппинг к вершинам объектов (просто увеличить прилипание к объектам)
мне нужно для объекта вызвать меню с действиями.
как это делается, не могли бы подсказать? я в qgis знаю чуть больше, чем 0.0 )))
-
lololol
- Участник
- Сообщения: 55
- Зарегистрирован: 11 фев 2016, 23:52
- Репутация: 0
Сообщение
lololol » 31 янв 2017, 16:08
причем я естественно должен знать, для какого именно объекта у меня вызвана менюшка.
-
Евгений Брусникин
- Новоприбывший
- Сообщения: 14
- Зарегистрирован: 31 май 2014, 14:21
- Репутация: 0
Сообщение
Евгений Брусникин » 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
Сообщение
lololol » 01 фев 2017, 07:14
Евгений Брусникин писал(а):
условие пересечения объектов. Если перескаются индентифицируем по любому столбцу слоя.
не уверен, что реализуемо на лету, но для 2 статичных (не редактируемых) слоев подходит
а если я работаю с одним слоем? точнее у меня будет один слой с точками и несколько прочих слоев для создание фона.
не совсем сообразил, ведь в этом примере нет точки координат мыши. Или я что то не понимаю или как с его помощью определять, что текушее положение мыши попадает в некую область вокруг какой-либо точки?
-
lololol
- Участник
- Сообщения: 55
- Зарегистрирован: 11 фев 2016, 23:52
- Репутация: 0
Сообщение
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
Сообщение
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 гость