Miałem działającą wtyczkę w QGIS 1.8, która odczytywała dane z bazy danych MSAccess i dodała je do szeregu warstw pamięci. Tymczasowe przetwarzanie wiąże się z pewnym przetwarzaniem, więc nie sądzę, aby używanie QGIS do odczytu bezpośrednio z bazy danych było opcją.
Chciałbym przejść z QGIS 1.8 do 1.9 (głównie ze względu na lepszą jakość kompozytora wydruku). Wtyczka nie działa z nowym interfejsem API.
Wypróbowałem wiele metod, które pojawiły się w wyszukiwaniach Google. Jeden, modyfikując poniższy kod - z http://www.qgis.org/pyqgis-cookbook/vector.html#memory-provider , tj. Dodając geometrię i atrybuty do dostawcy danych, a następnie aktualizując warstwę - w celu dopasowania do nowego API działającego trochę, ale atrybuty nie były widoczne, dopóki ręcznie nie przeszedłem do trybu edycji (podobnie do http://hub.qgis.org/issues/3713 ). Alternatywne podejście, szczegółowo opisane w odpowiedzi nr 1 powyższego łącza, dodało warstwę i atrybuty poprawnie, ale nie mogłem dodać funkcji do warstwy.
Biorąc pod uwagę, że powinno to być dość proste zadanie, mam nadzieję, że ktoś tutaj może zaoferować praktyczny przykład tego, jak należy to zrobić. (PS Nie jestem profesjonalnym programistą i większość mojego kodowania jest dość prymitywna - z zadowoleniem przyjmuję wszelkie wskazówki, ale proszę o usprawiedliwienie mojej niewiedzy)
# Receivers = a list of lists returned from a database query
# create layer
vl = QgsVectorLayer("Point", item, "memory")
pr = vl.dataProvider()
# add fields
pr.addAttributes( [ QgsField("Rec_No", QVariant.Int), QgsField("Include", QVariant.String), QgsField("Label", QVariant.String), QgsField("X", QVariant.Double),
QgsField("Y", QVariant.Double), QgsField("Z", QVariant.Double), QgsField("Height", QVariant.Double),
QgsField("Project_Re", QVariant.String), QgsField("NCA", QVariant.String),
QgsField("DayCrit", QVariant.Int), QgsField("EveCrit", QVariant.Int), QgsField("NightCrit", QVariant.Int) ] )
for i in range(len(Receivers)):
# add a feature
fet = QgsFeature()
X = Receivers[i][3]
Y = Receivers[i][4]
fet.setGeometry( QgsGeometry.fromPoint(QgsPoint(X,Y)) )
# Details = a list of results returned from a database query specific to each result in 'Receivers'
if Receivers[i][3] != 0:
Include = 'Yes'
else:
Include = 'No'
fet.setAttributeMap( { 0 : QVariant(Receivers[i][0]), 1 : QVariant(Include), 2 : QVariant(Receivers[i][2]),
3 : QVariant(Receivers[i][3]), 4 : QVariant(Receivers[i][4]), 5 : QVariant(Receivers[i][5]), 6 : QVariant(Receivers[i][6]),
7 : QVariant(Details[0]), 8 : QVariant(Details[1]), 9 : QVariant(Details[2]), 10 : QVariant(Details[3]), 11 : QVariant(Details[4]) } )
pr.addFeatures( [ fet ] )
# add a style
vl.loadNamedStyle('C:/OSGeo4W/apps/qgis/python/plugins/Gopher2QGIS/styles/Receiver_Style.qml')
# update layer's extent when new features have been added
# because change of extent in provider is not propagated to the layer
vl.commitChanges()
vl.updateExtents()
vl.updateFieldMap()
QgsMapLayerRegistry.instance().addMapLayer(vl)
Odpowiedzi:
Dzięki gsherman powyżej wtyczki PinPoint przykład jest idealny.
Jak rozumiem, proces jest następujący:
Oto fragment mojego kodu, który teraz działa.
źródło
Na podstawie odpowiedzi Adama Biolettiego dalsze testy opisanego procesu pokazują, że jedynym niezbędnym wymogiem jest rozpoczęcie edycji warstwy pamięci przed wprowadzeniem jakichkolwiek zmian, takich jak tworzenie atrybutów i funkcji, a następnie zatwierdzenie zmian. Można to zrobić przed dodaniem warstwy do rejestru map.
Oto aktualizacja kodu Cookbook, który współpracuje z API 2.0:
źródło