{"id":7776,"date":"2018-12-04T07:30:14","date_gmt":"2018-12-04T10:30:14","guid":{"rendered":"http:\/\/www.fernandoquadro.com.br\/html\/?p=7776"},"modified":"2018-12-05T08:06:55","modified_gmt":"2018-12-05T11:06:55","slug":"desenvolvimento-de-plugins-do-qgis-vizinho-mais-proximo-parte-3","status":"publish","type":"post","link":"https:\/\/www.fernandoquadro.com.br\/html\/2018\/12\/04\/desenvolvimento-de-plugins-do-qgis-vizinho-mais-proximo-parte-3\/","title":{"rendered":"Desenvolvimento de plugins do QGIS: Vizinho mais pr\u00f3ximo"},"content":{"rendered":"<p>No <a href=\"http:\/\/www.fernandoquadro.com.br\/html\/2018\/12\/03\/desenvolvimento-de-plugins-do-qgis-usando-o-console-parte-2\/\" rel=\"noopener\" target=\"_blank\">\u00faltimo post<\/a> foi descrito o b\u00e1sico da manipula\u00e7\u00e3o de camadas vetoriais. Como o nosso objetivo \u00e9 criar um plug-in personalizado totalmente funcional com base em uma dist\u00e2ncia, gostaria de discutir a indexa\u00e7\u00e3o espacial e a an\u00e1lise do vizinho mais pr\u00f3ximo.<\/p>\n<p><center><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2018\/11\/qgis.png\" alt=\"\" width=\"559\" height=\"149\" class=\"aligncenter size-full wp-image-7777\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2018\/11\/qgis.png 559w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2018\/11\/qgis-300x80.png 300w\" sizes=\"auto, (max-width: 559px) 100vw, 559px\" \/><\/center><\/p>\n<p>A figura acima ilustra a tarefa que pode ser resolvida apenas usando a API do QGIS. Imagine que voc\u00ea tenha uma camada de origem com um atributo preenchido com valores. Voc\u00ea recebe uma camada de destino tamb\u00e9m, infelizmente, os valores nesta camada est\u00e3o faltando (n\u00e3o t\u00e3o raros no mundo GIS, certo?). No entanto, voc\u00ea sabe que o valor ausente de cada recurso na camada de destino pode ser preenchido pelo valor de seu vizinho mais pr\u00f3ximo da camada de origem. Como voc\u00ea faz isso?<\/p>\n<p><strong>1. GERANDO DADOS FICT\u00cdCIOS<\/strong><\/p>\n<p>Vamos criar dois conjuntos de dados na mem\u00f3ria com atributos id e value. Ambos ter\u00e3o dez recursos.<\/p>\n<pre>\r\nfrom qgis.core import QgsMapLayerRegistry, QgsVectorLayer, QgsFeature, QgsGeometry, QgsPoint, QgsSpatialIndex\r\nfrom qgis.utils import iface\r\n\r\nsource_layer = QgsVectorLayer(\"point?crs=epsg:4326&amp;field=id:integer&amp;field=value:integer\", \"Source layer\", \"memory\")\r\ntarget_layer = QgsVectorLayer(\"point?crs=epsg:4326&amp;field=id:integer&amp;field=value:integer\", \"Target layer\", \"memory\")\r\n\r\ndef create_dummy_data():\r\n\r\n    source_layer.startEditing()\r\n    target_layer.startEditing()\r\n\r\n    feature = QgsFeature(source_layer.pendingFields())\r\n\r\n    for i in range(10):\r\n        feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(i, i)))\r\n        feature.setAttribute(\"id\", i)\r\n        feature.setAttribute(\"value\", i)\r\n        source_layer.addFeature(feature)\r\n\r\n    feature = QgsFeature(source_layer.pendingFields())\r\n\r\n    for i in range(10):\r\n        feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(i + i, i)))\r\n        feature.setAttribute(\"id\", i)\r\n        target_layer.addFeature(feature)\r\n\r\n    source_layer.commitChanges()\r\n    target_layer.commitChanges()\r\n\r\n    QgsMapLayerRegistry.instance().addMapLayer(source_layer)\r\n    QgsMapLayerRegistry.instance().addMapLayer(target_layer)\r\n\r\ncreate_dummy_data()\r\n<\/pre>\n<p><strong>2. ESCREVENDO VALORES DO VIZINHO MAIS PR\u00d3XIMO<\/strong><\/p>\n<p>A an\u00e1lise real do vizinho mais pr\u00f3ximo pode ser feita em dez linhas de c\u00f3digo! Primeiro, o qgis.core.QgsSpatialIndex \u00e9 constru\u00eddo a partir de todos os recursos <strong>source_layer<\/strong>. Ent\u00e3o, voc\u00ea itera sobre os recursos <strong>target_layer<\/strong> e para cada um deles, obt\u00e9m apenas um ( nearestNeighbor(f.geometry().asPoint(), 1)[0]) vizinho mais pr\u00f3ximo. Por fim, voc\u00ea apenas grava o valor do atributo do vizinho mais pr\u00f3ximo na camada de destino e confirma as altera\u00e7\u00f5es. <\/p>\n<pre>\r\ndef write_values_from_nn():\r\n    source_layer_index = QgsSpatialIndex(source_layer.getFeatures())\r\n    source_layer_features = {feature.id(): feature for (feature) in source_layer.getFeatures()}\r\n    target_layer_features = target_layer.getFeatures()\r\n\r\n    target_layer.startEditing()\r\n\r\n    for f in target_layer_features:\r\n        nearest = source_layer_index.nearestNeighbor(f.geometry().asPoint(), 1)[0]\r\n        value = source_layer_features[nearest].attribute(\"value\")\r\n        target_layer.changeAttributeValue(f.id(), 1, value)\r\n\r\n    target_layer.commitChanges()\r\n\r\nwrite_values_from_nn()\r\n<\/pre>\n<p><strong>3. O QUE VEM POR AI<\/strong><\/p>\n<p>Estamos um pouco mais perto do nosso objetivo.<a href=\"http:\/\/www.fernandoquadro.com.br\/html\/2018\/12\/05\/desenvolvimento-de-plugins-do-qgis-criando-interface-grafica-parte-4\/\" rel=\"noopener\" target=\"_blank\"> O que esta faltando<\/a>?<\/p>\n<ul>\n<li> Verifica\u00e7\u00f5es de capacidades: a camada de destino suporta edi\u00e7\u00f5es? Verifique os recursos do provedor de dados da camada para descobrir. <\/li>\n<li> Registro do usu\u00e1rio: avisos ou erros est\u00e3o completamente ausentes. Ser\u00e1 \u00f3timo t\u00ea-los apresentados dentro do qgis.gui.QgsMessageBar. <\/li>\n<li> Atributos customizados: essa vers\u00e3o espera que as duas camadas tenham o mesmo atributo com o mesmo tipo de dados. <\/li>\n<li> GUI : um widget PyQt transformar\u00e1 esse script baseado em console em um plug-in personalizado. Isso \u00e9 o que vamos ver no pr\u00f3ximo post. <\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>No \u00faltimo post foi descrito o b\u00e1sico da manipula\u00e7\u00e3o de camadas vetoriais. Como o nosso objetivo \u00e9 criar um plug-in personalizado totalmente funcional com base em uma dist\u00e2ncia, gostaria de discutir a indexa\u00e7\u00e3o espacial e a an\u00e1lise do vizinho mais&#8230; <a class=\"more-link\" href=\"https:\/\/www.fernandoquadro.com.br\/html\/2018\/12\/04\/desenvolvimento-de-plugins-do-qgis-vizinho-mais-proximo-parte-3\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":275,"featured_media":7779,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[79,260],"class_list":["post-7776","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gis","tag-python","tag-qgis"],"_links":{"self":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/7776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/users\/275"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/comments?post=7776"}],"version-history":[{"count":6,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/7776\/revisions"}],"predecessor-version":[{"id":7824,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/7776\/revisions\/7824"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media\/7779"}],"wp:attachment":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media?parent=7776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/categories?post=7776"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/tags?post=7776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}