آموزش نرم افزارQGIS (مقدماتی تا پیشرفته) قسمت6


 گسترش QGIS با پایتون

این فصل مقدمه ای بر اسکریپت نویسی QGIS با پایتون است. البته، یک آموزش کامل پایتون برای این کتاب خارج از محدوده است. بنابراین، مثال‌های اینجا حداقل مهارت کار با پایتون را فرض می‌کنند. Python یک زبان برنامه نویسی بسیار در دسترس است حتی اگر تازه شروع کرده اید، و هم در دنیای متن باز و هم در دنیای اختصاصی GIS، به عنوان مثال، ArcPy یا PyQGIS ESRI محبوبیت زیادی به دست آورده است. QGIS در حال حاضر از Python 2.7 پشتیبانی می کند، اما برنامه هایی برای پشتیبانی از Python 3 در سری های آینده QGIS 3.x وجود دارد. قبل از اینکه به توسعه پیشرفته تر ابزارهای سفارشی برای جعبه ابزار پردازش و توضیح نحوه ایجاد پلاگین های خودمان بپردازیم، با مقدمه ای بر اقدامات شروع می کنیم و سپس به کنسول پایتون QGIS می رویم.

افزودن عملکرد با استفاده از اقدامات

Actions یک راه راحت برای افزودن عملکرد سفارشی به QGIS است. کنش‌ها برای لایه‌های خاصی ایجاد می‌شوند، برای مثال مجموعه داده مکان‌های پرجمعیت ما،popp.shp. بنابراین برای ایجاد اکشن ها به قسمت Layer Properties | می رویم اقدامات. انواع مختلفی از اقدامات وجود دارد، مانند موارد زیر:

  • اقدامات عمومی شروع فرآیندهای خارجی؛ به عنوان مثال، شما برنامه های خط فرمان مانند ogr2ogr را اجرا می کنید

توجه داشته باشید

ogr2ogr یک ابزار خط فرمان است که می تواند برای تبدیل فرمت فایل ها و در عین حال انجام عملیات هایی مانند انتخاب فضایی یا ویژگی ها و بازپروژه استفاده شود.

  • اقدامات پایتون اسکریپت های پایتون را اجرا کنید
  • اقدامات بازبا استفاده از برنامه پیش‌فرض پیکربندی‌شده رایانه‌تان، یعنی برنامه مشاهده PDF خود، یک فایل را باز کنیدpdfفایل ها یا مرورگر شما برای وب سایت ها
  • عملکردهای سیستم عامل (مک، ویندوز و یونیکس) مانند اقدامات عمومی عمل می کنند اما به سیستم عامل مربوطه محدود می شوند.

پیکربندی اولین اقدام پایتون

روی دکمه افزودن اقدامات پیش‌فرض در سمت راست کادر گفتگو کلیک کنید تا چند نمونه از اقدامات را به شما اضافه کنیدپاپلایه. این واقعا برای شروع با اقدامات مفید است. به عنوان مثال، اکشن پایتون به نام Selected field’s value مقدار مشخصه مشخص شده را زمانی که از ابزار اقدام استفاده می کنیم نمایش می دهد. تنها کاری که باید انجام دهیم قبل از اینکه بتوانیم این عمل را امتحان کنیم این است که آن را به‌روزرسانی کنیم تا به یک ویژگی معتبر لایه ما دسترسی پیدا کند. به عنوان مثال، ما می توانیم آن را نمایش دهدپاپلایه هایتایپ کنیدمقدار ویژگی در یک جعبه پیام، همانطور که در تصویر بعدی نشان داده شده است:

  1. عمل مقدار فیلد انتخاب شده را در لیست اقدام انتخاب کنید.
  2. کد Action را در پایین کادر گفتگو ویرایش کنید. می توانید به صورت دستی نام ویژگی را وارد کنید یا آن را از لیست کشویی انتخاب کنید و روی فیلد Insert کلیک کنید.
  3. برای ذخیره تغییرات، روی Update Selected action کلیک کنید:

 

برای استفاده از این عمل، کادر گفتگوی Layer Properties را ببندید و روی فلش کشویی کنار دکمه Run Feature Action کلیک کنید. همانطور که در تصویر زیر نشان داده شده است، لیست اقدامات لایه موجود را گسترش می دهد:

روی ورودی مقدار فیلد Selected کلیک کنید و سپس بر روی ویژگی لایه کلیک کنید. با این کار یک گفتگوی پاپ آپ باز می شود که در آن اکشن ویژگی ها را خروجی می دهدتایپ کنیدمقدار. البته، می‌توانیم این خروجی اکشن را نیز اطلاعات بیشتری ارائه دهیم، به عنوان مثال، با گسترش آن به این:

QtGui.QMessageBox.information(هیچکدام، “مقدار فیلد فعلی”، “نوع: [% “TYPE” %] \n[% “F_CODEDESC” %]”)

این نشان می دهدتایپ کنیدارزش در خط اول وF_CODEDESCمقدار در خط دوم

باز کردن فایل ها با استفاده از اکشن ها

برای باز کردن فایل‌ها مستقیماً از داخل QGIS، از Open Actions استفاده می‌کنیم. اگر اقدامات پیش‌فرض را در تمرین قبلی اضافه کرده باشید، لایه شما قبلاً دارای یک اکشن فایل Open است. عمل به همین سادگی است[٪ “مسیر” ٪]برای باز کردن مسیر فایل مشخص شده در ویژگی path لایه. از آنجایی که هیچ یک از مجموعه داده های نمونه ما حاوی ویژگی مسیر نیستند، اکنون برای آزمایش این ویژگی یکی را اضافه می کنیم. وارسی فصل 3، ایجاد و ویرایش داده ها، اگر نیاز به دانستن جزئیات نحوه افزودن یک ویژگی جدید دارید. به عنوان مثال، مسیرهایی که در تصویر زیر اضافه شده اند، به ترتیب برنامه نمایش پیش فرض تصویر و نمایشگر PDF را باز می کنند:

در حالی که مثال قبلی از مسیرهای مطلق ذخیره شده در ویژگی ها استفاده می کند، شما همچنین می توانید با تغییر کد عمل از مسیرهای نسبی استفاده کنید تا مسیر جزئی ذخیره شده در مقدار مشخصه تکمیل شود. برای مثال می توانید استفاده کنیدC:\temp\[% “TYPE” %].pngبازکردن.pngفایل هایی که با توجه به نام گذاری شده اندتایپ کنیدمقادیر ویژگی

باز کردن یک مرورگر وب با استفاده از اقدامات

نوع دیگری از عملکرد مفید Open باز کردن مرورگر وب و دسترسی به وب سایت های خاص است. برای مثال این عمل را در نظر بگیرید:

http://www.google.com/search?q=[% “TYPE” %]

مرورگر وب پیش فرض شما را باز می کند و آن را جستجو می کندتایپ کنیدارزش با استفاده از Google، و این عمل:.

https://en.wikipedia.org/w/index.php?search=[% “TYPE” %]

در ویکی پدیا جستجو خواهد کرد.

آشنایی با کنسول پایتون

مستقیم ترین راه برای تعامل با QGIS API (مخفف Application Programming Interface) از طریق کنسول Python است که با رفتن به Plugins می توانید آن را باز کنید | کنسول پایتون همانطور که در تصویر زیر می بینید، کنسول پایتون در یک پنل جدید در زیر نقشه نمایش داده می شود:

نقطه دسترسی ما برای تعامل با برنامه، پروژه و داده استافسانه هدف – شی. برای دریافت لیستی از تمام عملکردهای موجود برایافسانه، نوعکمک (چهره). از طرف دیگر، این اطلاعات به صورت آنلاین در اسناد API در دسترس استhttp://qgis.org/api/classQgisInterface.html.

بارگیری و کاوش مجموعه داده ها

یکی از اولین کارهایی که می خواهیم انجام دهیم این است که مقداری داده را بارگذاری کنیم. به عنوان مثال، برای بارگذاری یک لایه برداری، از عبارت استفاده می کنیمaddVectorLayer()عملکردافسانه:

v_layer = iface.addVectorLayer(‘C:/Users/anita/Documents/Geodata/qgis_sample_data/shapefiles/airports.shp’,’airports’,’ogr’)

وقتی این دستور را اجرا می کنیم،Airports.shpبا استفاده ازogrراننده و با نام لایه به نقشه اضافه شدفرودگاه ها. علاوه بر این، این تابع ایجاد شده را برمی گرداندلایههدف – شی. با استفاده از اینلایهشی – که در آن ذخیره کردیمv_لایهما می توانیم به توابع لایه برداری مانندنام()، که نام لایه را برمی گرداند و در لیست لایه ها نمایش داده می شود:

v_layer.name()

این خروجی است:

تو فرودگاه ها

توجه داشته باشید

درتوروبرویفرودگاه هانام لایه نشان می دهد که نام به عنوان یک رشته یونیکد برگردانده شده است.

البته مرحله منطقی بعدی بررسی ویژگی های لایه است. با استفاده از این قابلیت می توان به تعدادی از ویژگی ها دسترسی داشتfeatureCount():

v_layer.featureCount()

در اینجا خروجی است:

76 لیتر

این به ما نشان می دهد که لایه فرودگاه دارای 76 ویژگی است. درLدر پایان نشان می دهد که یک مقدار عددی از نوع طولانی است. در مرحله بعدی به این ویژگی ها دسترسی خواهیم داشت. این امکان با استفاده ازgetFeatures()تابع، که a را برمی گرداندQgsFeatureIteratorهدف – شی. با یک سادهبرایحلقه، سپس می توانیم آن را چاپ کنیمویژگی های()از تمام ویژگی های لایه ما:

my_features = v_layer.getFeatures()برای ویژگی در my_features: print feature.attributes()

این خروجی است:

[1, u’US00157′, 78.0, u’Airport/Airfield’, u’PA’, u’NOATAK’ …

[2, u’US00229′, 264.0, u’Airport/Airfield’, u’PA’, u’AMBLER’…

[3, u’US00186′, 585.0, u’Airport/Airfield’, u’PABT’, u’BETTL…


نکته

هنگام استفاده از قطعه کد قبلی، شایان ذکر است که سینتکس پایتون به تورفتگی مناسب نیاز دارد. این بدان معنی است که، برای مثال، محتوایبرایهمانطور که در کد قبلی نشان داده شده است، حلقه باید تورفتگی داشته باشد. اگر پایتون با چنین خطاهایی مواجه شود، یک خطای تورفتگی ایجاد می کند.

شاید متوجه شده باشیدویژگی های()مقادیر ویژگی ها را به ما نشان می دهد، اما هنوز نام فیلدها را نمی دانیم. برای دریافت نام فیلدها از این کد استفاده می کنیم:

برای فیلد در v_layer.fields(): print field.name()

خروجی به صورت زیر است:

شناسه

fk_region

ELEV

نام

استفاده کنید

هنگامی که نام فیلدها را می دانیم، می توانیم به ویژگی های خاصی دسترسی داشته باشیم، به عنوان مثال،نام:

برای ویژگی در v_layer.getFeatures(): print feature.attribute(‘NAME’)

این خروجی است:

NOATAK

آمبلر

BTTLES


برای مثال، یک راه حل سریع برای جمع کردن مقادیر ارتفاع به شرح زیر است:

sum([feature.attribute(‘ELEV’) برای ویژگی در v_layer.getFeatures()])

در اینجا خروجی است:

22758.0

توجه داشته باشید

در مثال قبلی، ما از این واقعیت استفاده کردیم که پایتون به ما اجازه می دهد با نوشتن a یک لیست ایجاد کنیمبرایحلقه داخل پرانتز مربع به این کار درک لیست می گویند و می توانید اطلاعات بیشتری در مورد آن در اینجا بخوانیدhttps://docs.python.org/2/tutorial/datastructures.html#list-comprehensions.

بارگذاری داده های رستری بسیار شبیه به بارگذاری داده های برداری است و با استفاده از آن انجام می شودaddRasterLayer():

r_layer = iface.addRasterLayer(‘C:/Users/anita/Documents/Geodata/qgis_sample_data/raster/SR_50M_alaska_nad.tif’,’hillshade’)r_layer.name()

خروجی زیر است:

تو سایه

برای بدست آوردن اندازه لایه رستری بر حسب پیکسل می توانیم از آن استفاده کنیمعرض ()وارتفاع ()توابع، مانند این:

r_layer.width()، r_layer.height()

در اینجا خروجی است:

(1754، 1394)

اگر بخواهیم در مورد مقادیر رستری بیشتر بدانیم، از شیء ارائه دهنده داده لایه استفاده می کنیم که دسترسی به آمار باند رستری را فراهم می کند. شایان ذکر است که باید استفاده کنیمbandStatistics (1)بجایbandStatistics(0)برای دسترسی به آمار یک رستری تک باند، مانند ماسایه تپهلایه (به عنوان مثال، برای حداکثر مقدار):

r_layer.dataProvider().bandStatistics(1).maximumValue

خروجی به صورت زیر است:

251.0

مقادیر دیگری که می توان از این قبیل به آنها دسترسی داشت عبارتند ازحداقل مقدار،دامنه،stdDev، ومجموع. برای فهرست کامل، از این خط استفاده کنید:

help(r_layer.dataProvider().bandStatistics(1))

لایه های یک ظاهر طراحی شده

از آنجایی که اکنون می دانیم چگونه داده ها را بارگذاری کنیم، می توانیم به استایل دادن به لایه ها ادامه دهیم. ساده ترین گزینه بارگذاری یک سبک از پیش ساخته است (الفqmlفایل):

v_layer.loadNamedStyle(‘C:/temp/planes.qml’)v_layer.triggerRepaint()

حتما تماس بگیریدtriggerRepaint()برای اطمینان از اینکه نقشه دوباره ترسیم شده است تا تغییرات شما را منعکس کند.

توجه داشته باشید

شما می توانید ایجاد کنیدهواپیماها.qmlبا ذخیره سبک فرودگاهی که در آن ایجاد کردیدفصل 2، مشاهده داده های فضایی (با رفتن به قسمت Layer Properties | Style | Save Style | QGIS Layer Style File)، یا از هر سبک دیگری که دوست دارید استفاده کنید.

البته می توانیم یک استایل در کد نیز ایجاد کنیم. بیایید نگاهی به یک رندر اصلی تک نماد بیندازیم. یک نماد ساده با یک لایه ایجاد می کنیم، به عنوان مثال، یک الماس زرد:

از PyQt4.QtGui واردات QColorsymbol = QgsMarkerSymbolV2()symbol.symbolLayer(0).setName(‘diamond’)symbol.symbolLayer(0).setSize(10)symbol.symbolLayer(0).setColor(QColor(‘)#ffff0 )v_layer.rendererV2().setSymbol(symbol)v_layer.triggerRepaint()

یک رویکرد بسیار پیشرفته تر، ایجاد یک رندر مبتنی بر قانون است. ما در مورد اصول رندرهای مبتنی بر قانون بحث کردیم فصل 5، ایجاد نقشه های عالی. مثال زیر دو قانون ایجاد می کند: یکی برای فرودگاه های غیر نظامی و دیگری برای همه فرودگاه های دیگر. با توجه به طولانی بودن این اسکریپت، توصیه می کنم از ویرایشگر کنسول پایتون استفاده کنید که می توانید با کلیک بر روی دکمه Show editor آن را باز کنید، همانطور که در تصویر زیر نشان داده شده است:

هر قانون در این مثال دارای یک نام، یک عبارت فیلتر و یک رنگ نماد است. توجه داشته باشید که چگونه قوانین به قانون ریشه رندر اضافه می شوند:

from PyQt4.QtGui import QColorrules = [[‘Civil’,’USE LIKE \’%Civil%\”,’green’], [‘Other’,’USE NOT LIKE \’%Civil%\”,’red ‘]]symbol = QgsSymbolV2.defaultSymbol(v_layer.geometryType()) renderer = QgsRuleBasedRendererV2(symbol)root_rule = renderer.rootRule()برای برچسب، عبارت، نام_رنگ در قوانین: rule = root_clole(ne.child). ) rule.setLabel(label) rule.setFilterExpression(expression) rule.symbol().setColor(QColor(color_name)) root_rule.appendChild(rule)root_rule.removeChildAt(0)v_layer.setRendererV2(renderer.Regger_paint)

برای اجرای اسکریپت، روی دکمه Run script در پایین نوار ابزار ویرایشگر کلیک کنید.

نکته

اگر علاقه مند به خواندن بیشتر در مورد لایه های برداری یک ظاهر طراحی هستید، پست Joshua Arnott را توصیه می کنم.http://snorf.net/blog/2014/03/04/symbology-of-vector-layers-in-qgis-python-plugins/.

فیلتر کردن داده ها

برای فیلتر کردن ویژگی‌های لایه برداری به صورت برنامه‌ای، می‌توانیم یک رشته زیر مجموعه را مشخص کنیم. این همان تعریف یک جستجوی زیرمجموعه Feature در ویژگی های لایه | است بخش عمومی برای مثال، ما می‌توانیم انتخاب کنیم که فرودگاه‌ها فقط در صورتی نمایش داده شوند که نام آنها با علامت علامت شروع شودآ:

v_layer.setSubsetString (“NAME LIKE ‘A%'”)

برای حذف فیلتر، فقط یک رشته زیر مجموعه خالی را تنظیم کنید:

v_layer.setSubsetString(“”)

ایجاد یک لایه حافظه

یک راه عالی برای ایجاد یک لایه برداری موقت استفاده از لایه های به اصطلاح حافظه است. لایه های حافظه گزینه خوبی برای خروجی یا تجسم های تحلیل موقت هستند. آنها معادل اسکریپت لایه های اسکرچ موقت هستند که ما در آنها استفاده کردیم فصل 3، ایجاد و ویرایش داده ها. مانند لایه‌های اسکرچ موقت، لایه‌های حافظه در یک جلسه QGIS وجود دارند و با بسته شدن QGIS از بین می‌روند. در مثال زیر یک لایه حافظه ایجاد می کنیم و یک ویژگی چند ضلعی به آن اضافه می کنیم.

اساساً یک لایه حافظه یک استQgsVectorLayerمانند هر دیگری با این حال، ارائه دهنده (پارامتر سوم) نیست’اگر’همانطور که در مثال قبلی بارگذاری یک فایل، اما”حافظه”. به جای مسیر فایل، اولین پارامتر یک رشته تعریف است که نوع هندسه، CRS و فیلدهای جدول ویژگی را مشخص می کند (در این مورد، یک فیلد عدد صحیح به نامMYNUMو یک رشته رشته نامیده می شودMYTXT):

mem_layer = QgsVectorLayer(“Polygon?crs=epsg:4326&field=MYNUM:integer&field=MYTXT:string”، “temp_layer”، “memory”)اگر mem_layer.isValid نباشد(): Exception را افزایش دهید(“لایه حافظه ایجاد نشد”)

هنگامی که ما ایجاد کردیمQgsVectorLayerشی، ما می توانیم شروع به اضافه کردن ویژگی ها به ارائه دهنده داده آن کنیم:

mem_layer_provider = mem_layer.dataProvider()my_polygon = QgsFeature()my_polygon.setGeometry(QgsGeometry.fromRect(QgsRectangle(16,48,17,49))my_polygon.set,”melogonFeatures. my_polygon])QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

توجه داشته باشید

توجه داشته باشید که چگونه ابتدا یک خالی ایجاد می کنیمویژگی Qgs، که سپس هندسه و ویژگی ها را با استفاده از آن اضافه می کنیمsetGeometry()وsetAttributes()، به ترتیب. وقتی لایه را بهQgsMapLayerRegistry، لایه روی نقشه رندر می شود.

صادرات تصاویر نقشه

ساده ترین گزینه برای ذخیره نقشه فعلی استفاده از معادل اسکریپت Save as Image (تحت پروژه) است. این نقشه فعلی را به یک فایل تصویری با وضوح مشابه با منطقه نقشه در پنجره برنامه QGIS صادر می کند:

iface.mapCanvas().saveAsImage(‘C:/temp/simple_export.png’)

اگر بخواهیم کنترل بیشتری روی اندازه و وضوح تصویر صادر شده داشته باشیم، به چند خط کد دیگر نیاز داریم. مثال زیر نشان می دهد که چگونه می توانیم خودمان را ایجاد کنیمQgsMapRendererCustomPainterJobشیء کنید و با استفاده از سفارشی به دلخواه خود پیکربندی کنیدQgsMapSettingsبرای اندازه (عرضوارتفاع)، وضوح (dpi) نقشهوسعت، و نقشهلایه های:

از PyQt4.QtGui واردات QImage، QPainter از PyQt4.QtCore واردات QSize
# تصویر خروجی را پیکربندی کنید

عرض = 800 ارتفاع = 600dpi = 92img = QImage(QSize(عرض، ارتفاع)، QImage.Format_RGB32)img.setDotsPerMeterX(dpi / 25.4 * 1000)img.setDotsPerMeterY(dpi *100)
# لایه ها و وسعت نقشه را دریافت کنید

layers = [ layer.id() برای لایه در iface.legendInterface().layers() ]extent = iface.mapCanvas().extent()
# تنظیمات نقشه را برای صادرات پیکربندی کنید

mapSettings = QgsMapSettings()mapSettings.setMapUnits(0)mapSettings.setExtent(extent)mapSettings.setOutputDpi(dpi)mapSettings.setOutputSize(QSize(width, height))mapSize(عرض، ارتفاع))mapSizeSetting. UseAdvancedEffects | QgsMapSettings.ForceVectorOutput | QgsMapSettings.DrawLabeling)
# پیکربندی و اجرای painter

p = QPainter()p.begin(img)mapRenderer = QgsMapRendererCustomPainterJob(mapSettings، p)mapRenderer.start()mapRenderer.waitForFinished()p.end()
# نتیجه را ذخیره کنید

img.save(“C:/temp/custom_export.png”،”png”)

ایجاد اسکریپت های پردازش جغرافیایی سفارشی با استفاده از پایتون

که درفصل 4, Spatial Analysis , ما از ابزار Processing Toolbox برای تجزیه و تحلیل داده های خود استفاده کردیم اما به این ابزارها محدود نمی شویم. ما می توانیم پردازش را با اسکریپت های خودمان گسترش دهیم. مزایای پردازش اسکریپت ها نسبت به اسکریپت های معمولی پایتون، مانند مواردی که در قسمت قبل دیدیم، به شرح زیر است:

  • پردازش به طور خودکار یک رابط کاربری گرافیکی برای اسکریپت ایجاد می کند تا پارامترهای اسکریپت را پیکربندی کند
  • اسکریپت های پردازشی را می توان در Graphical Modeler برای ایجاد مدل های geoprocessing استفاده کرد

همانطور که تصویر زیر نشان می دهد، بخش Scripts در ابتدا خالی است، به جز برخی از ابزارها برای افزودن و ایجاد اسکریپت های جدید:

نوشتن اولین اسکریپت پردازش

ما اولین اسکریپت ساده خود را ایجاد خواهیم کرد. که برخی از اطلاعات لایه را واکشی می کند. برای شروع، روی ورودی ایجاد اسکریپت جدید در Scripts | دوبار کلیک کنید ابزار. این یک گفتگوی خالی ویرایشگر اسکریپت را باز می کند. تصویر زیر ویرایشگر اسکریپت را با یک اسکریپت کوتاه نشان می دهد که نام لایه ورودی را در کنسول پایتون چاپ می کند:

خط اول به این معنی است که اسکریپت ما در قسمت قرار خواهد گرفتیادگیری QGISگروهی از اسکریپت ها، همانطور که در تصویر زیر نشان داده شده است. هش های دوتایی (##) سینتکس پردازش هستند و نشان می دهند که این خط به جای کد پایتون حاوی اطلاعات خاص پردازش است. نام اسکریپت از نام فایلی که هنگام ذخیره اسکریپت انتخاب کردید ایجاد می شود. برای این مثال، من اسکریپت را به عنوان ذخیره کرده امmy_first_script.py. خط دوم ورودی اسکریپت را تعریف می کند که در این مورد یک لایه برداری است. در خط زیر از Processing استفاده می کنیمgetObject()تابع دسترسی به شی لایه ورودی است و در نهایت نام لایه در کنسول پایتون چاپ می شود.

می‌توانید اسکریپت را مستقیماً از داخل ویرایشگر با کلیک بر روی دکمه اجرای الگوریتم یا با دوبار کلیک کردن روی ورودی در جعبه ابزار پردازش اجرا کنید. اگر می خواهید کد را تغییر دهید، همانطور که در این تصویر نشان داده شده است، از ویرایش متن از منوی زمینه ورودی استفاده کنید:

نکته

یک راه خوب برای یادگیری نحوه نوشتن اسکریپت های سفارشی برای پردازش این است که نگاهی به اسکریپت های موجود بیندازید، به عنوان مثال، درhttps://github.com/qgis/QGIS-Processing/tree/master/scripts. این مخزن رسمی اسکریپت است که می توانید اسکریپت ها را با استفاده از ابزار داخلی Get scripts from on-line scripts collection در جعبه ابزار پردازش دانلود کنید.

نوشتن یک اسکریپت با خروجی لایه برداری

البته، در بیشتر موارد، ما نمی خواهیم فقط چیزی را در کنسول پایتون خروجی بگیریم. به همین دلیل است که مثال زیر نحوه ایجاد یک لایه برداری را نشان می دهد. به طور خاص، اسکریپت چند ضلعی های مربعی را در اطراف نقاط در لایه ورودی ایجاد می کند. عددیاندازهپارامتر ورودی اندازه مربع ها را کنترل می کندبردار خروجیلایه. اندازه پیش فرضی که در گفتگوی تولید شده به طور خودکار نمایش داده می شود، روی تنظیم شده است1000000:

##Learning QGIS=group##input_layer=vector##size=number 1000000##squares=output vectorfrom qgis.core import *from processing.tools.vector import VectorWriter
# لایه ورودی و فیلدهای آن را دریافت کنید

my_layer = processing.getObject(input_layer)fields = my_layer.dataProvider().fields()
# نوشتن بردار خروجی را با همان فیلدها ایجاد کنید

writer = VectorWriter(مربع، هیچ، فیلدها، QGis.WKBPolygon، my_layer.crs())
# ویژگی های خروجی ایجاد کنید

feat = QgsFeature()برای input_feature در my_layer.getFeatures():
# ویژگی ها را از ویژگی نقطه ورودی کپی کنید

ویژگی ها = input_feature.attributes() feat.setAttributes(ویژگی ها)
# چند ضلعی مربع ایجاد کنید

point = input_feature.geometry().asPoint() xmin = point.x() – size/2 ymin = point.y() – size/2 مربع = QgsRectangle(xmin,ymin,xmin+size,ymin+size) feat .setGeometry(QgsGeometry.fromRect(square)) writer.addFeature(feat)del writer

در این اسکریپت از a استفاده می کنیموکتورنویسبرای نوشتن لایه برداری خروجی پارامترهای ایجاد aوکتورنویسشی هستندنام فایل،رمزگذاری،زمینه های،geometryType، وcrs.

توجه داشته باشید

انواع هندسه موجود هستندQGis.WKBPoint،QGis.WKBLineString،QGis.WKBPolygon،QGis.WKBMultiPoint،QGis.WKBMultiLineString، وQGis.WKBMultiPolygon. شما همچنین می توانید این لیست از انواع هندسه را با تایپ کردن دریافت کنیدVectorWriter.TYPE_MAPدر کنسول پایتون

توجه داشته باشید که چگونه از فیلدهای لایه ورودی استفاده می کنیم (my_layer.dataProvider().fields()) برای ایجادوکتورنویس. این تضمین می کند که لایه خروجی دارای همان فیلدها (ستون های جدول ویژگی) با لایه ورودی است. به طور مشابه، برای هر ویژگی در لایه ورودی، مقادیر ویژگی آن را کپی می کنیم (input_feature.attributes()) به ویژگی خروجی مربوطه.

پس از اجرای اسکریپت، لایه حاصل در QGIS بارگذاری می شود و با استفاده از نام پارامتر خروجی فهرست می شود. در این حالت لایه نامیده می شودمربع ها. اسکرین شات زیر دیالوگ ورودی تولید شده به طور خودکار و همچنین خروجی اسکریپت را هنگام اعمال بر روی فرودگاه ها از مجموعه داده نمونه ما نشان می دهد:

تجسم پیشرفت فیلمنامه

به خصوص هنگام اجرای اسکریپت های پیچیده که مدتی طول می کشد تا به پایان برسد، تمرین خوبی است که پیشرفت اجرای اسکریپت را در نوار پیشرفت نمایش دهید. برای افزودن نوار پیشرفت به اسکریپت قبلی، می‌توانیم خطوط کد زیر را قبل و داخل آن اضافه کنیمبرایحلقه ای که از طریق ویژگی های ورودی حلقه می زند:

i = 0n = my_layer.featureCount() for input_feature در my_layer.getFeatures(): progress.setPercentage(int(100*i/n)) i+=1

توجه داشته باشید

توجه داشته باشید که ما مقدار را مقداردهی اولیه می کنیممنقبل از حلقه شمارنده و پس از به روز رسانی نوار پیشرفت با استفاده از آن، آن را در داخل حلقه افزایش دهیدprogress.setPercentage().

در حال توسعه اولین افزونه شما

هنگامی که می خواهید ابزارهای تعاملی یا رابط های کاربری گرافیکی بسیار خاصی را پیاده سازی کنید، زمان آن فرا رسیده است که به توسعه افزونه نگاه کنید. در تمرینات قبلی QGIS Python API را معرفی کردیم. بنابراین، اکنون می‌توانیم روی مراحل لازم برای شروع اولین پلاگین QGIS تمرکز کنیم. نکته جالب در مورد ایجاد پلاگین برای QGIS این است که یک افزونه برای این کار وجود دارد! پلاگین ساز نام دارد. و در حالی که در آن هستید، Plugin Reloader را نیز نصب کنید، که برای توسعه دهندگان افزونه بسیار مفید است. زیرا به شما این امکان را می دهد که هر بار که در کد تغییرات ایجاد می کنید، افزونه خود را بدون نیاز به راه اندازی مجدد QGIS مجدداً بارگیری کنید. وقتی هر دو پلاگین را نصب کردید، نوار ابزار Plugins شما به شکل زیر خواهد بود:

قبل از شروع، باید Qt Designer را نیز نصب کنیم، برنامه‌ای که برای طراحی رابط کاربری از آن استفاده خواهیم کرد. اگر از ویندوز استفاده می کنید، من WinPython را توصیه می کنم (http://winpython.github.io/) نسخه 2.7.10.3 (آخرین نسخه با پایتون 2.7 در زمان نگارش این کتاب) که Qt Designer و Spyder (یک محیط توسعه یکپارچه برای پایتون) را ارائه می دهد. در اوبونتو، می‌توانید Qt Designer را با استفاده از آن نصب کنیدsudo apt-get install qt4-designer. در مک، می توانید نصب کننده Qt Creator (که شامل Qt Designer است) را از آن دریافت کنیدhttp://qt-project.org/downloads.

ساخت قالب افزونه با افزونه ساز

افزونه ساز تمام فایل هایی را که ما برای پلاگین خود نیاز داریم ایجاد می کند. برای ایجاد یک قالب پلاگین، مراحل زیر را دنبال کنید:

  1. Plugin Builder را راه اندازی کنید و اطلاعات اصلی افزونه را وارد کنید، از جمله:
    • نام کلاس(یک کلمه در شتر، یعنی هر کلمه با یک حرف بزرگ شروع می شود)
    • نام افزونه(توضیح کوتاه)
    • نام ماژول(نام ماژول پایتون برای افزونه)

هنگامی که ماوس خود را روی فیلدهای ورودی در کادر گفتگوی Plugin Builder قرار می دهید، اطلاعات راهنما را نمایش می دهد، همانطور که در تصویر زیر نشان داده شده است:

  1. بر روی Next کلیک کنید تا به کادر گفتگوی About بروید، جایی که می توانید توضیحات دقیق تری از کاری که افزونه شما انجام می دهد را وارد کنید. از آنجایی که قصد داریم اولین پلاگین را فقط برای اهداف آموزشی ایجاد کنیم، می‌توانیم متنی تصادفی را در اینجا قرار داده و روی Next کلیک کنیم.
  2. اکنون می‌توانیم یک الگوی پلاگین را انتخاب کنیم و یک متن برای آیتم منو و همچنین فهرستی که افزونه باید در کدام منو قرار دهد، مشخص کنیم، همانطور که در تصویر زیر نشان داده شده است. الگوهای موجود شامل دکمه ابزار با گفتگو، دکمه ابزار با ویجت داک و ارائه دهنده پردازش است. در این تمرین، یک دکمه Tool با گفتگو ایجاد می کنیم و روی Next کلیک می کنیم:

  1. گفتگوی زیر چک باکس هایی را نشان می دهد، جایی که می توانیم انتخاب کنیم کدام فایل افزونه غیر ضروری باید ایجاد شود. می توانید هر زیر مجموعه ای از گزینه های ارائه شده را انتخاب کرده و بر روی Next کلیک کنید.
  2. در گفتگوی بعدی، باید افزونه Bug Tracker و مخزن کد را مشخص کنیم. باز هم، از آنجایی که ما این افزونه را فقط برای اهداف یادگیری ایجاد می کنیم، من فقط در تصویر بعدی چند URL ایجاد می کنم، اما اگر قصد دارید افزونه خود را در دسترس عموم قرار دهید، باید از ردیاب ها و مخازن کد مناسب استفاده کنید:

  1. پس از کلیک بر روی Next، از شما خواسته می شود که پوشه ای را برای ذخیره افزونه انتخاب کنید. می توانید آن را مستقیماً در پوشه افزونه QGIS ذخیره کنید،~\.qgis2\python\pluginsدر ویندوز، یا~/.qgis2/python/pluginsدر لینوکس و مک
  2. هنگامی که پوشه پلاگین را انتخاب کردید، یک گفتگوی تایید نتایج Plugin Builder نمایش داده می شود که مکان پوشه پلاگین شما و همچنین مکان پوشه پلاگین QGIS شما را تایید می کند. همانطور که قبلا ذکر شد، من مستقیماً در پوشه افزونه QGIS ذخیره کردم، همانطور که در تصویر زیر می بینید. اگر در مکان دیگری ذخیره کرده اید، اکنون می توانید پوشه افزونه را به پوشه افزونه های QGIS منتقل کنید تا مطمئن شوید که QGIS می تواند آن را پیدا و بارگیری کند:

 

یک کاری که هنوز باید انجام دهیم این است که نماد نوار ابزار افزونه را آماده کنیم. این مستلزم آن است که ما را کامپایل کنیممنابع.qrcفایلی که افزونه ساز به طور خودکار ایجاد کرده است تا نماد را به کد پایتون قابل استفاده تبدیل کند. این کار در خط فرمان انجام می شود. در ویندوز، من استفاده از پوسته OSGeo4W را توصیه می کنم، زیرا اطمینان حاصل می کند که متغیرهای محیطی به گونه ای تنظیم شده اند که ابزارهای لازم را پیدا کنید. به پوشه افزونه بروید و این را اجرا کنید:

pyrcc4 -o resources.py resources.qrc

نکته

می توانید نماد پیش فرض را جایگزین کنید (icon.png) برای اضافه کردن نماد افزونه خود. پس از آن، شما فقط باید دوباره کامپایل کنیدresources_rc.qrcهمانطور که قبلا نشان داده شده است.

QGIS را مجدداً راه اندازی کنید و اکنون باید افزونه خود را که در اینجا نشان داده شده است در فهرست مدیریت پلاگین ببینید:

افزونه خود را در Plugin Manager فعال کنید و باید آن را در فهرست Plugins مشاهده کنید. هنگامی که پلاگین خود را راه اندازی می کنید، یک گفتگوی خالی نمایش داده می شود که فقط منتظر شماست تا آن را سفارشی کنید.

سفارشی کردن رابط کاربری گرافیکی افزونه

برای سفارشی کردن دیالوگ پیش فرض خالی افزونه، از Qt Designer استفاده می کنیم. می توانید فایل گفتگو را در پوشه افزونه پیدا کنید. در مورد من به آن می گویندmy_first_plugin_dialog_base.ui(برگرفته از نام ماژول که در Plugin Builder مشخص کردم). وقتی پلاگین خود را باز می کنید.uiفایل در Qt Designer، دیالوگ خالی را خواهید دید. اکنون می توانید با کشیدن و رها کردن ویجت ها از جعبه ویجت در سمت چپ پنجره Qt Designer شروع به اضافه کردن ویجت کنید. در اسکرین شات زیر، می بینید که من یک ویجت Label و لیست کشویی را اضافه کردم (به عنوان Combo Box در ویجت باکس ذکر شده است). می توانید متن برچسب را به تغییر دهیدلایهبا دوبار کلیک کردن بر روی متن برچسب پیش فرض. علاوه بر این، تخصیص نام های توصیفی به اشیاء ویجت تمرین خوبی است. برای مثال، من کمبوباکس را به تغییر نام دادملایه ترکیبی، همانطور که در اینجا در گوشه سمت راست پایین مشاهده می کنید:

پس از اتمام تغییرات در گفتگوی افزونه، می توانید آنها را ذخیره کنید. سپس می توانید به QGIS برگردید. در QGIS، اکنون می توانید با کلیک بر روی دکمه Choose a plugin to be reloaded در نوار ابزار Plugins و انتخاب افزونه خود، Plugin Reloader را پیکربندی کنید. اگر اکنون روی دکمه Reload Plugin کلیک کنید و دکمه پلاگین خود را فشار دهید، گفتگوی افزونه جدید شما نمایش داده می شود.

پیاده سازی عملکرد افزونه

همانطور که مطمئناً متوجه شده اید، جعبه ترکیبی لایه هنوز خالی است. برای پر کردن جعبه ترکیبی با لیستی از لایه های بارگذاری شده، باید چند خط کد به آن اضافه کنیم.my_first_plugin.py(واقع درافزونهپوشه). به طور خاص، ما گسترش می دهیماجرا کن()روش:

def run(self run):
“””روش اجرا که تمام کارهای واقعی را انجام می دهد”””

# گفتگو را نشان دهید

self.dlg.show()
# جعبه ترکیبی را پاک کنید تا فقط لایه‌های فعلی فهرست شود

self.dlg.layerCombo.clear()
# لایه ها را بگیرید و به جعبه ترکیبی اضافه کنید

لایه ها = QgsMapLayerRegistry.instance().mapLayers().values() برای لایه در لایه ها: if layer.type() == QgsMapLayer.VectorLayer: self.dlg.layerCombo.addItem( layer.name()، لایه )
# حلقه رویداد گفتگو را اجرا کنید

نتیجه = self.dlg.exec_()
# ببینید OK فشار داده شده است یا خیر

اگر نتیجه:
# بررسی کنید که کدام لایه انتخاب شده است

index = self.dlg.layerCombo.currentIndex() لایه =self.dlg.layerCombo.itemData(index)
# نمایش اطلاعات در مورد لایه

QMessageBox.information(self.iface.mainWindow()،”آموزش QGIS”،”%s دارای %d ویژگی است.” %(layer.name(),layer.featureCount()))

همچنین باید خط واردات زیر را در بالای اسکریپت اضافه کنید تا از آن جلوگیری کنیدخطاهای ناممربوط بهQgsMapLayerRegistryوQMessageBox:

از واردات qgis.core *از PyQt4.QtGui واردات QMessageBox

پس از انجام تغییرات درmy_first_plugin.py، می توانید فایل را ذخیره کنید و از دکمه Reload Plugin در QGIS برای بارگذاری مجدد افزونه خود استفاده کنید. اگر پلاگین خود را هم اکنون راه اندازی کنید، کمبوباکس با لیستی از تمام لایه های پروژه فعلی QGIS پر می شود و با کلیک بر روی OK، کادر پیامی را مشاهده خواهید کرد که تعداد ویژگی های لایه انتخاب شده را نشان می دهد.

ایجاد یک ابزار نقشه سفارشی

در حالی که تمرین قبلی نحوه ایجاد یک رابط کاربری گرافیکی سفارشی را نشان می‌دهد که کاربر را قادر می‌سازد تا با QGIS تعامل داشته باشد، در این تمرین، ما یک قدم جلوتر خواهیم رفت و ابزار نقشه سفارشی خود را شبیه به ابزار پیش‌فرض Identify پیاده‌سازی می‌کنیم. این بدان معناست که کاربر می تواند روی نقشه کلیک کند و ابزار گزارش می دهد که روی کدام ویژگی روی نقشه کلیک شده است.

برای این منظور، یک دکمه ابزار دیگر با قالب افزونه گفتگو به نام ایجاد می کنیمMyFirstMapTool. برای این ابزار، ما نیازی به ایجاد دیالوگ نداریم. در عوض، باید کمی بیشتر از نمونه قبلی کد بنویسیم. ابتدا کلاس ابزار نقشه سفارشی خود را ایجاد می کنیم که آن را فراخوانی می کنیمIdentifyFeatureTool. علاوه بر__ابتدا__()سازنده، این ابزار تابعی به نام داردcanvasReleaseEvent()که عملکرد ابزار را هنگام رها شدن دکمه ماوس مشخص می کند (یعنی زمانی که دکمه ماوس را پس از فشار دادن آن رها می کنید):

class IdentifyFeatureTool(QgsMapToolIdentify): def __init__(self, canvas): QgsMapToolIdentify.__init__(self, canvas) def canvasReleaseEvent(self, mouseEvent): چاپ “canvasReleaseEvent”
# ویژگی ها را در موقعیت فعلی ماوس دریافت کنید

results = self.identify(mouseEvent.x()،mouseEvent.y()، self.TopDownStopAtFirst، self.VectorLayer) اگر len(نتایج) > 0:
# نشان می دهد که یک ویژگی شناسایی شده است

self.emit( ​​SIGNAL( “geomIdentified” ), results[0].mLayer, results[0].mFeature)

می توانید کد قبلی را در انتهای قسمت قرار دهیدmy_first_map_tool.pyکد البته، اکنون باید از ابزار نقشه جدید خود به خوبی استفاده کنیم. درinitGui()تابع، ما جایگزیناجرا کن()روش با جدیدmap_tool_init()عملکرد. علاوه بر این، ما تعریف می کنیم که ابزار نقشه ما قابل بررسی است. این بدان معناست که کاربر می تواند روی نماد ابزار کلیک کند تا فعال شود و دوباره روی آن کلیک کند تا غیرفعال شود:

def initGui(self):
# نماد نوار ابزار و ورودی منو را ایجاد کنید

icon_path = ‘:/plugins/MyFirstMapTool/icon.png’ self.map_tool_action=self.add_action(icon_path, text=self.tr(u’اولین ابزار نقشه من’)،
callback=self.map_tool_init،

parent=self.iface.mainWindow())
self.map_tool_action.setCheckable(True)

جدیدmap_tool_init()وقتی روی دکمه کلیک می‌کنید، تابع وظیفه فعال یا غیرفعال کردن ابزار نقشه ما را بر عهده دارد. در طول فعال سازی، یک نمونه از سفارشی ما ایجاد می کندIdentifyFeatureToolو خط زیر ابزار نقشه را به هم متصل می کندgeomIdentifiedسیگنال بهکاری بکنید()تابعی که در یک لحظه به آن خواهیم پرداخت. به همین ترتیب، هنگامی که ابزار نقشه غیرفعال می شود، سیگنال را قطع کرده و ابزار نقشه قبلی را بازیابی می کنیم:

def map_tool_init(self):
# وقتی روی نماد ابزار نقشه کلیک می شود، این تابع فراخوانی می شود

چاپ “maptoolinit” canvas = self.iface.mapCanvas() if self.map_tool_action.isChecked():
# وقتی کاربر ابزار را فعال می کند

self.prev_tool = canvas.mapTool() self.map_tool_action.setChecked( True ) self.map_tool = IdentifyFeatureTool(canvas) QObject.connect(self.map_tool,SIGNAL(“geomIdentified”), selfing.Map_tools map_tool) QObject.connect(canvas,SIGNAL(“mapToolSet(QgsMapTool *)”)، self.map_tool_changed) other:
# وقتی کاربر ابزار را غیرفعال می کند

QObject.disconnect(canvas,SIGNAL(“mapToolSet(QgsMapTool *)”),self.map_tool_changed) canvas.unsetMapTool(self.map_tool) چاپ “بازیابی ابزار قبلی %s” %(self.prev_tool) canvas.prev_tool. )

رسم جدید ماکاری بکنید()تابع زمانی فراخوانی می شود که از ابزار نقشه ما برای شناسایی موفقیت آمیز یک ویژگی استفاده شود. برای این مثال، ما به سادگی ویژگی های ویژگی را در کنسول پایتون چاپ می کنیم. البته، می‌توانید در اینجا خلاقیت به خرج دهید و عملکرد دلخواه خود را اضافه کنید:

def do_something(self، لایه، ویژگی): print feature.attributes()

در نهایت، زمانی که کاربر به یک ابزار نقشه دیگر سوئیچ می‌کند، باید به این مورد رسیدگی کنیم. این مشابه حالتی است که کاربر ابزار ما را در آن غیرفعال می کندmap_tool_init()عملکرد:

def map_tool_changed(self): print “maptoolchanged” canvas = self.iface.mapCanvas() QObject.disconnect(canvas,SIGNAL(“mapToolSet(QgsMapTool *)”)، self.map_tool_changed) canvas.unsetfMapTool.pol map_tool_action.setChecked(False)

همچنین باید خط واردات زیر را در بالای اسکریپت اضافه کنید تا از خطاهای مربوط به آن جلوگیری کنیدQObject،QgsMapTool، و دیگران:

از واردات qgis.core *از واردات qgis.gui *از واردات PyQt4.QtCore *

وقتی آماده شدید، می‌توانید افزونه را دوباره بارگیری کنید و آن را امتحان کنید. شما باید کنسول پایتون را باز داشته باشید تا بتوانید خروجی های افزونه را دنبال کنید. اولین چیزی که هنگام فعال کردن افزونه در نوار ابزار مشاهده خواهید کرد، چاپ آن استmaptoolinitروی کنسول سپس اگر روی نقشه کلیک کنید، چاپ می شودcanvasReleaseEventو اگر روی یک ویژگی کلیک کنید، ویژگی های ویژگی را نیز نمایش می دهد. در نهایت، اگر به ابزار نقشه دیگری (مثلاً ابزار Pan Map) تغییر دهید، چاپ خواهد شدنقشه ابزار تغییر کرددر کنسول و علامت نوار ابزار افزونه برداشته می شود.

خلاصه

در این فصل، روش‌های مختلف گسترش QGIS با استفاده از اکشن‌ها و اسکریپت‌نویسی پایتون را پوشش می‌دهیم. ما با انواع مختلف اکشن ها شروع کردیم و سپس به کنسول پایتون ادامه دادیم، که یک راه مستقیم و تعاملی برای تعامل با QGIS Python API ارائه می دهد. ما همچنین از ویرایشگری استفاده کردیم که بخشی از پنل کنسول پایتون است و روش بهتری برای کار بر روی اسکریپت‌های طولانی‌تر حاوی حلقه‌ها یا حتی تعاریف کلاس و تابع چندگانه ارائه می‌دهد. در مرحله بعد، ما دانش خود را از PyQGIS برای توسعه ابزارهای سفارشی برای جعبه ابزار پردازش به کار بردیم. این ابزارها از قابلیت‌های تولید خودکار رابط کاربری گرافیکی Processing سود می‌برند و می‌توان از آنها در مدل‌سازی گرافیکی برای ایجاد مدل‌های پردازش جغرافیایی استفاده کرد. آخرین اما نه کم‌اهمیت، ما یک پلاگین اساسی بر اساس یک الگوی افزونه ساز توسعه دادیم.

با این دانش پس زمینه، اکنون می توانید آزمایش های PyQGIS خود را شروع کنید. چندین منبع وب و چاپ وجود دارد که می توانید از آنها برای کسب اطلاعات بیشتر در مورد برنامه نویسی Python QGIS استفاده کنید. برای اسناد به روز شده QGIS API، بررسی کنیدhttp://qgis.org/api/. اگر به دستور العمل های PyQGIS بیشتری علاقه مند هستید، به کتاب آشپزی توسعه دهنده PyQGIS نگاهی بیندازید.http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbookو کتاب های برنامه نویسی QGIS ارائه شده توسط انتشارات Packt و همچنین کتاب The PyQGIS Programmer’s Guide نوشته گری شرمن، Locate Press.

برگرفته از کتاب آموزش کاربردی QGIS

مترجم:دکتر سعید جوی زاده،ونوس نصیرفام

15 نظرات

دیدگاهتان را بنویسید