Daha çox

Printly Composer-da Openlayers plagin qatını proqramlı olaraq istifadə edin

Printly Composer-da Openlayers plagin qatını proqramlı olaraq istifadə edin


Bir çap bəstəkarı qurmaq, düzeni dəyişdirmək (xəritələr, əfsanə, başlıq əlavə etmək) və nəticəni bir şəkil faylı olaraq çap etmək üçün bəzi PyQGIS funksiyaları yaratdım. Bu bir və ya bir neçə vektor təbəqəsi ilə yaxşı işləyir - hamısı nəticələnən görüntü sənədində göstərilir.

Lakin, Openlayers plaginindən bir qat daxil edən bir bəstəkar düzümü yaratmağa çalışdığımda, gözlənilən nəticəni ala bilmirəm - əksər hallarda bazemap təbəqəsi ümumiyyətlə itkin olur və bəzən bəzi əsərlər görünür.

Aşağıdakı nümunə kodu qurduqdan sonra dərhal icra olunmalıdırplotdiryuxarıdakı parametr, istədiyiniz çıxış qovluğuna. O

  • yeni bir QGIS layihəsi yaradır
  • yaddaşda hər biri bir nöqtə həndəsəsi olan iki vektor qatı yaradır
  • OpenStreetMap əsas xəritəsini OpenLayers plaginindən yükləyir (başqa şəkildə necə yüklədiyimi bilmədiyim üçün QGIS Gui menyusunu tıklayaraq)
  • iki yaddaş qatını və Openlayers qatını yeni yaradılmış çap bəstəkarına ötürür, bəzi düzəltmə materialları (əfsanə, başlıq ...) təyin edir və nəticəni bir şəkil sənədinə saxlayır.

Bunu işlətdiyim zaman, əfsanə istənilən üç təbəqəni göstərir, lakin kətan boşdur (nöqtə həndəsələri olduqca kiçik olduğundan ən azı əsas xəritəni görməyi gözləyərdim). PyQGIS ilə bir çap xəritəsini bir çap bəstəkarına düzgün bir şəkildə daxil etmək üçün təklifiniz varmı? Bunu QGIS 2.4 və 2.6 ilə Windows 7-də sınadım.

Kod:

# qgis.core import * qgis.utils import * PyQt4.QtCore import * PyQt4.QtGui import * plotdir = r'F:  '############### ##################### # yeni bir qgis layihəsinə başlamaq üçün # funksiya ####################### ############## def startNewProject (): print ('yeni layihə başlayır') iface.newProject (thePromptToSaveFlag = False) return ############### ###################### # yaddaş qatını yaratmaq və xəritə qat qeydinə əlavə etmək funksiyası ################ ##################### def createMemoryLayer (layerType, layerName, x, y): çap 'yaddaş qat yaratmaq' myMemoryLayer = QgsVectorLayer (layerType, layerName, "yaddaş") QgsMapLayerRegistry.instance (). AddMapLayer (myMemoryLayer, True) feat = QgsFeature () feat.setGeometry (QgsGeometry.fromPoint (QgsPoint (x, y)))) (res, outFeats) = myMemoryLayer.dataPiders ) myMemoryLayer ##################################################################################################################### # ilə işləsək ############# təbəqə ağacının dibi ############ ########################## def loadOpenLayersPluginMap (mapProvider, openLayersMap): print 'loading openlayers plugin layer' webMenu = iface.webMenu () #get object of webMenu.actions () içərisində webMenuItem üçün QGIS Veb menyusu: # QGIS Veb menyusunu açın və webMenuItem.text () 'də "OpenLayers plagini" varsa veb plaginlər siyahısını nəzərdən keçirin: Vebdə OpenLayers plagin girişi üçün #look menu openLayersMenu = webMenuItem # və openLayersMenuItem üçün openLayersMenu.menu () açın. tədbirlər (): # OpenLayers plagin menyu girişini açın və xəritə təminatçıları siyahısından keçin, əgər MapProvider openLayersMenuItem.text (): #ifustProvider mapProviderMenu = openLayersMenuItem # mapProviderMenu.menu () içərisində xəritə üçün menyu girişini açın. tədbirlər (): # açılan provayder üçün xəritələrin siyahısını nəzərdən keçirin map.text (): # istədiyiniz xəritə girişi olduqda found map.trigger () # xəritəni bir təbəqə kimi yükləmək üçün girişə klikləyin # digər layları qoyaraq qatı TOC-nin altına köçürün. yuxarıdakılar (openlayers təbəqəsi birbaşa köçürülə bilməz) root = QgsProject.instance (). layerTreeRoot () in root.children (): if isinstance (child, QgsLayerTreeLayer): childClone = child.clone () root.insertChildNode ( 0, childClone) root.removeChildNode (child) return #################################### # zoom funksiyası bir təbəqə dərəcəsinə qədər ##################################### def zoomToLayerExtent (qat): çap 'yaxınlaşdırma təbəqəyə '# istədiyiniz qatı aktiv olaraq təyin edin və ona yaxınlaşdırın iface.setActiveLayer (qat) iface.zoomToActiveLayer () return ######################## ########### # xəritənin tərtibatını xəritə bəstəkarı ilə şəkil faylı olaraq saxlamaq funksiyası ########################## ######### def saveImagesWithPrintComposer (təbəqələr, scaleLayer, plottitle, plotdir): çap 'bəstəkar ilə qənaət şəkilləri' ####### # qat dəsti qurun, genişləndirin və xəritə göstəricisi yaradın ## ##### mapRenderer = QgsMapSettings () # QGIS 2.4-də yeni - QgsMapRenderer () layerSet əvəz edir [qat-qatdakı qat üçün]] creat QgsMapRenderer istifadə edilərkən MapRenderer.setLayers (layerSet) # kompozisiyasının bir hissəsi olan bütün qat kimliklərinin ea siyahısı, bunu setLayerSet (təbəqə dəsti) mapRectangle = arrangLayer.extent () # istədiyiniz qat mapRectangle dərəcəsinə uyğun olaraq təyin edin. miqyas (2) # istədiyiniz kimi miqyas təyin edin mapRenderer.setExtent (mapRectangle) mapRenderer.setOutputSize (QSize (1600,1200)) # # QgsMapRenderer () istifadə edərkən setOutputSize ikinci bir arqumentə ehtiyac duyur '[int] dpi' ###### # # bir kompozisiya yaradın və işləyicidən keçin ####### kompozisiya = QgsComposition (mapRenderer) tərkibi.setPlotStyle (QgsComposition.Print) dpi = compos.printResolution () dpmm = dpi / 25.4 width = int (dpmm * kompozisiya. paperWidth ()) height = int (dpmm * kompozisiya.paperHeight ()) ####### # kompozisiyaya xəritə əlavə et ####### x, y = 0, 0 w, h = kompozisiya.paperWidth (), kompozisiya.paperHeight () composerMap = QgsComposerMap (kompozisiya, x, y, w, h) kompozisiya.addItem (composerMap) ####### # başlıq yaradın ####### composerLa bel = QgsComposerLabel (kompozisiya) composerLabel.setText (plottitle) composerLabel.setFont (QFont ("Arial", 8)) composerLabel.adjustSizeToText () composerLabel.setBackgroundEnabled (False) composition.addItem (composerLabel.abel1010) ####### # əfsanə yaradın ####### # bəstəkar əfsanə obyekti yaradın composerLegend = QgsComposerLegend (kompozisiya) # dəst əfsanə qatlarını düzəldin (xəritə təbəqəsi ilə eyni) composerLegend.model (). setLayerSet ( mapRenderer.layers ()) # QgsMapRenderer istifadə edərkən, qatların yerinə layerSet () istifadə edin () # set başlıqları composerLegend.setTitle (") newFont = QFont (" Arial ", 8) composerLegend.setStyleFont (QgsComposerLegendStyle.Title, .setStyleFont (QgsComposerLegendStyle.Subgroup, newFont) composerLegend.setStyleFont (QgsComposerLegendStyle.SymbolLabel, newFont) # refresh legend composerLegend.updateLegend () # set function countem activate activate bütün təbəqələr teFeatureCount (qat): composerLayerItem.setLayerID (layer.id ()) composerLayerItem.setShowFeatureCount (True) return [activateFeatureCount (layer) for layer in layer] # set legend background composerLegend.setBackgroundEnabled (False) # set legend positionet 20,20) # kompozisiya kompozisiyasına əfsanə əlavə edin .addItem (composerLegend) ####### # şəkil yaradın və başladın ####### image = QImage (QSize (genişlik, hündürlük), QImage.Format_ARGB32) görüntü .setDotsPerMeterX (dpmm * 1000) image.setDotsPerMeterY (dpmm * 1000) image.fill (0) ####### # Render kompozisiya ####### rəssam = QPainter (image) sourceArea = QRectF (0, 0, texture.paperWidth (), kompozisiya.paperHeight ()) targetArea = QRectF (0, 0, width, height) kompozisiya.render (painter, targetArea, sourceArea) painter.end () ####### # Save şəkil sənədinə kompozisiya (digər uzantılar mümkündür) ####### image.save (plotdir + plottitle + '.png ">

Openlayers plagini xəritə bəstəkarları ilə işləmir - yalnız əsas xəritə kətanında işləyir. Digərləri arasında http://hub.qgis.org/issues/5827, http://hub.qgis.org/issues/8824 və ya http://hub.qgis.org/issues/10992 baxın ...


Proqramlaşdırılmış şəkildə yaradılmış çap kompozisiyasında birbaşa Openlayers plagin qatından istifadə etmək mümkün olmadığına görə (qəbul olunmuş cavaba baxın), bu yanaşma ən azı istədiyiniz Openlayers xəritəsi ölçüsündən sabit bir şəkil faylı (jpg / png) yaratmaq üçün istifadə edilə bilər. Bəlkə də bu kiməsə birtəhər faydalıdır ...

Python konsolunda işləyən bir PyQGIS skriptindən zəng edilə bilməsi üçün biraz dəyişdirdiyim basemap2Image skriptinə əsaslanır. Onu istifadə etmək üçün aşağıdakı köməkçi funksiyalara ehtiyacınız var.

Bir vektor qatının kənar koordinatlarını əldə etmək:

###################################### # qat qatının koordinatlarını əldə etmək funksiyası ###### ############################## def getCoordinatesOfLayerExtent (qat): çap 'qat dərəcəsinin koordinatlarını almaq' layerRectangle = layer.extent () koordinatlar = [layerRectangle.xMinimum (), layerRectangle.yMinimum (), layerRectangle.xMaximum (), layerRectangle.yMaximum ()] qayıt koordinatları

QgsVectorLayer obyekti təqdim edərək zəng edin, məsələn.

vectorLayerCoordinates = getCoordinatesOfLayerExtent (myFavoriteVectorLayer)

Koordinatlar EPSG-də skriptə ötürülməlidir: 3857, buna görə vektor təbəqəniz bu CRS-i standart olaraq istifadə etmirsə, əvvəlcə koordinatları çevirmək üçün aşağıdakı funksiyanı istifadə edin:

####################################### # koordinat dəstini bir CRS-dən digərinə çevirmək funksiyası ## ################################### def transformKoordinatlar (koordinatlar, fromCRS, toCRS): çap 'crs arasında dəyişən koordinatlar' crsSrc = QgsCoordinateReferenceSystem (fromCRS) crsDest = QgsCoordinateReferenceSystem (toCRS) xform = QgsCoordinateTransform (crsSrc, crsDest) # koordinatların siyahısını QgsPoint obyektlərinə çevirmə əlaqələndirirAsPoints = koordinatlar [QgsPoint] , koordinatlar [3])] # hər nöqtə üçün transformasiya edir transformedCoordinatesAsPoints = [xform.transform (point) in coordinateAsPoints in point for] # QgsPoint obyektlərini yenidən transformasiya edilmiş koordinatlar siyahısına çevirir transformedCoordinates = [transformedCoordinatesAsPoints [0] .x (), transformedCoordinatesAsPoints [0] .y (), transformedCoordinatesAsPoints [1] .x (), transformedCoordinatesAsPoints [1] .y ()] return transformedCoordinates

Koordinatlar siyahınızı, mənşə CRS və istədiyiniz təyinat CRS-lərinizi təqdim edərək zəng edin, məsələn:

transformedCoordinatlar = transformCoordinatlar (koordinatlar, 4326, 3857)

İndi boş bir fayl yaradın__init__.pyskriptinizin yanında (bu, eyni qovluqdakı digər skriptlərdən funksiyaları idxal etmək üçün lazımdır) və başqası, buna bənzər (bu dəyişdirilmiş basemap2Image skriptidir):

#! / usr / bin / env python # 30 Kasım 2012 # Angel Joyce Torres Ramirez # [email protected] # Bu proqrama verdiyiniz hər hansı bir istifadəyə görə cavabdeh deyiləm, öz-özümə təhsil və təhsil məqsədləri etdim # Lisenziya: # BaseMap2Image pulsuz proqramdır; Pulsuz Proqram Vəqfi tərəfindən yayımlandığı kimi GNU Ümumi Dövlət Lisenziyası şərtlərinə uyğun olaraq yenidən paylaya və / və ya dəyişdirə bilərsiniz; ya Lisenziyanın 2-ci versiyası, ya da hər hansı bir sonrakı versiya. qgis.core-dan idxal sys idxal siqnalı. qgis.utils-dən idxal * PyQt4.QtCore-dan idxal * PyQt4.QtGui-dən idxal * PyQt4.QtWebKit-dən idxal * functools-dan idxal qismən def main (htmlDirectory, arg1, arg2, arg3, arg4 , arg5, arg6, arg7, arg8): arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 def onLoadFinished (nəticə): global repaintEnd global xMin global yMin global xMax global yMax global width global height global fileOut global fileFormat nəticə verməzsə: "İstək alınmadı" yazdır web.close () action = "map.zoomToExtent (yeni OpenLayers.Bounds (" + xMin + "," + yMin + "," + xMax + "," + yMax + "), true); " web.page (). mainFrame (). evalJavaScript (fəaliyyət) repaintEnd = Yoxdur pauseReq () img = QImage (web.page (). mainFrame (). ContentSize (), QImage.Format_ARGB32_Premultiplied) imgPainter = QPainter (img) page (). mainFrame (). render (imgPainter) imgPainter.end () img = img.scaled (genişlik, hündürlük, Qt.KeepAspectRatio, Qt.SmoothTransformation) img.save (fileOut, fileFormat) çap 'qənaət bazemap' web. close () def pauseReq (): global repaintEnd timerMax.start () while repaintEnd: qApp.processEvents () timerMax.stop () def endTimer (): global repaintEnd repaintEnd = True def qətnamələr (): olResolutions == None: resVariant = web.page (). mainFrame (). evalJavaScript ("map.layers [0] .resolutions") olResolutions = [] resVariant.toList () dəki res üçün: olResolutions.append (res.toDouble () [0] ) return olResolutions qlobal qat qat = arg1 global xMin xMin = arg2 global yMin yMin = arg3 global xMax xMax = arg4 global yMax yMax = arg5 global fileOut fileOut = arg6 global fileFormat fileFormat = "png" if fileOut.fi nd (".")! = -1: fileFormat = fileOut.split ('.') [1] əgər fileFormat == "jpg": fileFormat = "jpeg" timeWait = 2000 qlobal genişlik eni = float (arg7) qlobal hündürlük height = float (arg8) web = QWebView () timerMax = QTimer () global repaintEnd repaintEnd = Yok olResolutions = Yok timerMax.setSingleShot (True) timerMax.setInterval (int (timeWait)) QObject.connect (timerMax, SIGNAL (") ) "), endTimer) web.setFixedSize (genişlik, hündürlük) pathUrl =" fayl: ///%s/%s.html "% (htmlDirectory, layer) web.connect (web, SIGNAL (" loadFinished (bool) ") ), onLoadFinished) web.load (QUrl (pathUrl)) web.show ()

Bu skriptin əsas funksiyasına zəng etmək üçün aşağıdakı arqumentləri verməlisiniz:

  1. htmlDirectory: yolhtmlgithub paketinin bir hissəsi olan qovluq (anbarı klonlayın və ya zip olaraq yükləyin, sonra html qovluğunu əlverişli bir yerə kopyalayın)

  2. mapProvider: arasından birini seçinhtmlmüvafiq .html sənədinin mövcud olduğu qovluq, məs. 'google_streets' və ya 'osm'

  3. xMin: EPSG-də qat dərəcəsi koordinatları: 3857

  4. yMin: EPSG-də qat dərəcəsi koordinatları: 3857

  5. xMax: EPSG-də qat dərəcəsi koordinatları: 3857

  6. yMax: EPSG-də qat dərəcəsi koordinatları: 3857

  7. fayl adı: çıxış şəklinin yolu və fayl adı

  8. genişlik: Çıxış görüntü sənədinin genişliyi

  9. hündürlük: Çıxış görüntü sənədinin hündürlüyü

Skript əvvəlcə başqa növlərin olmadığı əmr sətrindən istifadə olunmaq üçün inkişaf etdirildiyi üçün bütün mübahisələri sətir kimi keçirdiyinizə əmin olun. Nümunəvi bir zəng belə görünə bilər:

basemap2Image.main (r'c:  PyQGIS  html ',' osm ', str (transformedCoordinates [0]), str (transformedCoordinates [1]), str (transformedCoordinates [2]), str (transformedCoordinates [3]), r'c:  PyQGIS  basemap.png "> konsolu harada axtaracağını söyləməlisiniz. Bunu etməyimin ən asan və ən qalıcı yolu fayl axtarışı idikonsol.pyQGIS qovluğuma əlavə edin və sətri əlavə edinsys.path.append ('/ path / to / basemap2Image script')idxal bölməsi altında (dəyişikliyi xəbərdar etmək üçün QGIS-i yenidən başladın).

Belə sadə bir xüsusiyyət üçün çox iş var ... lakin bunu yuxarıda göstərildiyi kimi işlədərkən, istədiyiniz Openlayers provayderinizin bir dünya xəritəsini göstərən bir pəncərə açılmalı, sonra verilmiş ölçüdə böyütmək, məzmunu verilmiş fayl adına və sonra pəncərəni yenidən bağlayın. Bu şəkil faylı daha sonra bir baza xəritəsi və ya çap tərkibində başqa hər hansı bir şey kimi istifadə edilə bilər.


Videoya baxın: Create, Modify and Label a Point Feature in QGIS