ऑर्थो प्रोजेक्शन कलाकृतियों का उत्पादन करता है


14

मैं क्यूजीस और "स्पेस से दुनिया" का उपयोग करके एक क्षेत्र जैसा दृश्य बनाने की कोशिश कर रहा हूं -प्रोजेक्शन http://spatialreference.org/ref/sr-org/6980/ (जरूरी एक ओर्थो-प्रोजेक्शन)। आर्कजीआईएस आकृतियों को सही ढंग से लपेटता है लेकिन क्यूजीआईएस (2.01) गंदा कलाकृतियों का उत्पादन करता है।

यहाँ छवि विवरण दर्ज करें

मुझे अलग-अलग कोणों के साथ नियमित रूप से ग्लोब का उत्पादन करना है तो क्या किसी को पता है कि इस समस्या को कैसे ठीक किया जाए?


1
संबंधित QGIS बग रिपोर्ट: hub.qgis.org/issues/2703
n

क्या ऑर्थोग्राफिक प्रोजेक्शन को पहले से लोड किया जाना बहुत बड़ी तकनीकी समस्या है, जिसे फिर से किसी भी दृश्य पर केंद्रित किया जा सकता है?

इस सवाल का जवाब नहीं है। कृपया यह जानने के लिए दौरे पर जाएं कि एक फोकस्ड प्रश्न कैसे पूछा जाए।
जॉन पॉवेल

जवाबों:


23

जैसा कि आंद्रे ने कहा, इसे काम करने के लिए, आपको प्रोजेक्ट करने से पहले अपनी परत की आवश्यकता होगी। आंद्रे एक मैनुअल विधि का वर्णन करता है, जो बहुत सारे मामलों के लिए अच्छी तरह से काम करता है: अपनी आकृति आकृति को ऑज़मोग्राफिक प्रोजेक्शन के समान अज़िमुथल इक्वेडिस्टेंट प्रोजेक्शन के साथ प्रोजेक्ट करें, एक क्लिपिंग सर्कल बनाएं जो गोलार्ध को कवर करता है जो ऑर्थोग्राफ़िक प्रोजेक्शन में दिखाई देगा, और उस के साथ आकृति को क्लिप करें। हालाँकि, उस विधि के लिए थोड़े से मैनुअल प्रयास की आवश्यकता होती है, और सभी प्रोजेक्शन मापदंडों के लिए काम नहीं करता है, क्योंकि अज़ीमुथल इक्विडिस्टेंट प्रोजेक्शन के लिए प्रोजेक्ट करने से ऑर्थोग्राफ़िक प्रोजेक्शन के समान प्रॉब्लम हो सकती है।

यहां एक स्क्रिप्ट (अब क्लिप टू हेमिस्फेयर क्यूजीआईएस प्लगइन के रूप में भी उपलब्ध है ) जो थोड़ा अलग दृष्टिकोण लेती है: ऑर्थोग्राफ़िक से स्रोत सीआरएस के एक सर्कल को प्रोजेक्ट करके मूल आकृति आकृति के समन्वय संदर्भ प्रणाली में एक क्लिपिंग परत बनाई जाती है, लेकिन इसके अतिरिक्त दृश्यमान ध्रुव सहित पूरे दृश्यमान गोलार्ध को कवर करना सुनिश्चित करें।

यह वह क्लिपिंग परत है जो 30 ° N, 110 ° E पर केंद्रित ऑर्थोग्राफ़िक प्रोजेक्शन के लिए दिखती है:

स्क्रिप्ट तब क्लिपिंग परत के साथ वर्तमान में चयनित परत को क्लिप करती है, और परिणामी परत को प्रोजेक्ट में जोड़ती है। उस परत को ऑर्थोग्राफिक प्रोजेक्शन के लिए प्रोजेक्ट किया जा सकता है, या तो मक्खी पर या ऑर्थोग्राफ़िक सीआरएस में इसे सहेज कर:

यहाँ स्क्रिप्ट है। इसे अपने पाइथन पथ में सहेजना सुनिश्चित करें, उदाहरण के लिए 'क्लिपोरथो-थ्रू'। तब आप इसका उपयोग कर QGIS पायथन कंसोल में आयात कर सकते हैं import cliportho। एक लेयर को क्लिप करने के लिए, कॉल करें cliportho.doClip(iface, lat=30, lon=110, filename='A.shp')


import numpy as np
from qgis.core import *
import qgis.utils

import sys, os, imp


def doClip(iface, lat=30, lon=110, filename='result.shp'):
    sourceLayer = iface.activeLayer()

    sourceCrs = sourceLayer.dataProvider().crs()

    targetProjString = "+proj=ortho +lat_0=" + str(lat) + " +lon_0=" + str(lon) + "+x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs"
    targetCrs = QgsCoordinateReferenceSystem()
    targetCrs.createFromProj4(targetProjString)

    transformTargetToSrc = QgsCoordinateTransform(targetCrs, sourceCrs).transform

    def circlePolygon(nPoints=20, radius=6370000, center=[0,0]):
        clipdisc = QgsVectorLayer("Polygon?crs=epsg:4326", "Clip disc", "memory")
        angles = np.linspace(0, 2*np.pi, nPoints, endpoint=False)
        circlePoints = np.array([ transformTargetToSrc(QgsPoint(center[0]+np.cos(angle)*radius, center[1]+np.sin(angle)*radius)) for angle in angles ])
        sortIdx = np.argsort(circlePoints[:,0])
        circlePoints = circlePoints[sortIdx,:]
        circlePoints = [ QgsPoint(point[0], point[1]) for point in circlePoints ]
        circlePoints.extend([QgsPoint(180,circlePoints[-1][1]), QgsPoint(180,np.sign(lat)*90), QgsPoint(-180,np.sign(lat)*90), QgsPoint(-180,circlePoints[0][1])])
        circle = QgsFeature()
        circle.setGeometry(QgsGeometry.fromPolygon( [circlePoints] ) )
        clipdisc.dataProvider().addFeatures([circle])
        QgsMapLayerRegistry.instance().addMapLayer(clipdisc)
        return clipdisc

    auxDisc = circlePolygon(nPoints = 3600)

    ###### The clipping stuff
    ## Code taken from the fTools plugin

    vproviderA = sourceLayer.dataProvider()
    vproviderB = auxDisc.dataProvider()

    inFeatA = QgsFeature()
    inFeatB = QgsFeature()
    outFeat = QgsFeature()

    fitA = vproviderA.getFeatures()

    nElement = 0  
    writer = QgsVectorFileWriter( filename, 'UTF8', vproviderA.fields(),
                                  vproviderA.geometryType(), vproviderA.crs() )

    index = QgsSpatialIndex()
    feat = QgsFeature()
    index = QgsSpatialIndex()
    fit = vproviderB.getFeatures()
    while fit.nextFeature( feat ):
        index.insertFeature( feat )

    while fitA.nextFeature( inFeatA ):
      nElement += 1
      geom = QgsGeometry( inFeatA.geometry() )
      atMap = inFeatA.attributes()
      intersects = index.intersects( geom.boundingBox() )
      first = True
      found = False
      if len( intersects ) > 0:
        for id in intersects:
          vproviderB.getFeatures( QgsFeatureRequest().setFilterFid( int( id ) ) ).nextFeature( inFeatB )
          tmpGeom = QgsGeometry( inFeatB.geometry() )
          if tmpGeom.intersects( geom ):
            found = True
            if first:
              outFeat.setGeometry( QgsGeometry( tmpGeom ) )
              first = False
            else:
              try:
                cur_geom = QgsGeometry( outFeat.geometry() )
                new_geom = QgsGeometry( cur_geom.combine( tmpGeom ) )
                outFeat.setGeometry( QgsGeometry( new_geom ) )
              except:
                GEOS_EXCEPT = False
                break
        if found:
          try:
            cur_geom = QgsGeometry( outFeat.geometry() )
            new_geom = QgsGeometry( geom.intersection( cur_geom ) )
            if new_geom.wkbType() == 0:
              int_com = QgsGeometry( geom.combine( cur_geom ) )
              int_sym = QgsGeometry( geom.symDifference( cur_geom ) )
              new_geom = QgsGeometry( int_com.difference( int_sym ) )
            try:
              outFeat.setGeometry( new_geom )
              outFeat.setAttributes( atMap )
              writer.addFeature( outFeat )
            except:
              FEAT_EXCEPT = False
              continue
          except:
            GEOS_EXCEPT = False
            continue
    del writer

    resultLayer = QgsVectorLayer(filename, sourceLayer.name() + " - Ortho: Lat " + str(lat) + ", Lon " + str(lon), "ogr")
    QgsMapLayerRegistry.instance().addMapLayer(resultLayer)

बहुत आशाजनक लग रहा है - मैं निश्चित रूप से इसे आज़माऊंगा और प्रतिक्रिया प्रदान करने में प्रसन्न रहूंगा। मैं थोड़ा चापलूसी प्रोग्रामिंग में हूँ, लेकिन क्यूगिस प्रोग्रामिंग के साथ शुरू नहीं किया है - लेकिन मैं यह समझने की कोशिश करूँगा कि आप क्या कर रहे हैं;; एक प्लगइन (शायद कई परतों के लिए काम करने वाला बैच) इतना मददगार होगा!
user1523709

1
FYI करें, यह स्क्रिप्ट अब "FTools" पैकेज को हटाने के कारण QGIS 2.16 में काम नहीं करती है।
स्पाइक विलियम्स

2
@SpikeWilliams: मैंने fTools पर निर्भरता को हटाने के लिए स्क्रिप्ट को अपडेट किया है।
जेक

5

आपको विश्व के दृश्यमान आधे हिस्से में अपने बहुभुज डेटा को क्रॉप करना होगा, क्योंकि क्यूजीआईएस स्वयं ऐसा नहीं करता है।

मैंने यहाँ एक ट्यूटोरियल लिखा है:

QGIS में नक्शा पेश करने के बाद बहुभुज कहाँ गए?


संपादित करें

आप जो चित्र दिखाते हैं, वह वास्तव में ऑर्थो प्रोजेक्शन नहीं है, क्योंकि यह पूरी दुनिया को दिखाता है, न कि केवल बाहरी भाग से दिखाई देने वाला आधा हिस्सा। विश्व मानचित्रों के लिए, कटिंग थोड़ी आसान है, जैसा कि यहाँ वर्णित है:

QGIS प्रदर्शन दुनिया के देश आकार की फाइलें रॉबिन्सन, मिलर बेलनाकार या अन्य प्रक्षेपण का उपयोग कर प्रशांत महासागर पर केंद्रित हैं


धन्यवाद आंद्रे, जो समस्या को समझने में काफी मददगार था - लेकिन चूंकि मुझे एक दैनिक आधार पर इस तरह के ग्लोब बनाने हैं और बदलते दृष्टिकोण के साथ इसमें बहुत सारे मैनुअल काम की आवश्यकता होती है। क्या आप किसी भी प्लग-इन आदि के बारे में जानते हैं। अपने समाधान को स्वचालित करने के लिए?
user1523709

एक बार जब आप एक क्लिपिंग सर्कल बनाते हैं, तो बाकी को बैच स्क्रिप्ट का उपयोग करके कमांड लाइन स्तर पर GDAL का उपयोग करके किया जा सकता है।
आंद्रेजे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.