qgis와 "world from space"-projection http://spatialreference.org/ref/sr-org/6980/ (본질적으로 정사영) 을 사용하여 구와 같은 뷰를 만들려고합니다 . ArcGIS는 모양을 올바르게 래핑하지만 QGIS (2.01)는 불규칙한 아티팩트를 생성합니다.
다른 각도로 지구본을 정기적으로 만들어야하므로이 문제를 해결하는 방법을 아는 사람이 있습니까?
qgis와 "world from space"-projection http://spatialreference.org/ref/sr-org/6980/ (본질적으로 정사영) 을 사용하여 구와 같은 뷰를 만들려고합니다 . ArcGIS는 모양을 올바르게 래핑하지만 QGIS (2.01)는 불규칙한 아티팩트를 생성합니다.
다른 각도로 지구본을 정기적으로 만들어야하므로이 문제를 해결하는 방법을 아는 사람이 있습니까?
답변:
Andre가 말했듯이 이것이 작동하려면 레이어를 투영하기 전에 자르기해야합니다. Andre 는 많은 경우에 잘 작동 하는 수동 방법에 대해 설명합니다 . 직교 투영과 동일한 매개 변수를 사용하여 형상 파일을 방위각 등거리 투영으로 투영하고, 직교 투영에서 볼 수있는 반구를 덮는 클리핑 원을 생성합니다. 그것으로 shapefile을 자르십시오. 그러나 방위각 등거리 투영으로 투영 할 때 직교 투영법으로 투영 할 때와 유사한 문제가 발생할 수 있기 때문에이 방법에는 약간의 수동 노력이 필요하며 모든 투영 매개 변수에서 작동하지 않습니다.
다음 은 약간 다른 접근법을 취하는 스크립트 (현재 Clip to Hemisphere QGIS 플러그인 으로도 사용 가능 )입니다. 직교에서 소스 CRS로 원을 투영하여 원본 셰이프 파일의 좌표 참조 시스템에 클리핑 레이어가 생성됩니다. 보이는 극을 포함하여 전체 보이는 반구를 덮어야합니다.
30 ° N, 110 ° E를 중심으로하는 직교 투영의 경우 클리핑 레이어는 다음과 같습니다.
그런 다음 스크립트는 현재 선택된 레이어를 클리핑 레이어로 자르고 결과 레이어를 프로젝트에 추가합니다. 그런 다음 해당 레이어를 직교 투영 방식으로 투영하거나 직교 CRS에 저장하여 투영 할 수 있습니다.
여기 스크립트가 있습니다. 파이썬 경로에 저장하십시오 (예 : 'cliportho.py'). 그런 다음을 사용하여 QGIS Python 콘솔에서 가져올 수 있습니다 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)
QGIS는 자체적으로 그렇게하지 않기 때문에 다각형 데이터를 지구의 보이는 절반으로 잘라야합니다.
나는 여기에 튜토리얼을 썼다 :
QGIS에서 맵을 투영 한 후 다각형은 어디로 갔습니까?
편집하다
당신이 보여준 그림은 실제로는 전체 공간을 보여주기 때문에 직교 투영이 아닙니다. 세계지도의 경우 다음과 같이 절단이 조금 더 쉽습니다.
QGIS는 Robinson, Miller Cylindrical 또는 기타 투영법을 사용하여 태평양을 중심으로 세계 국가 모양 파일을 표시합니다.