Як сказав Андре, для цього вам потрібно обрізати шар, перш ніж проектувати його. Андре описує ручний метод , який добре працює у багатьох випадках: спроектуйте свій файл форми на азимутальну рівновіддалену проекцію з тими ж параметрами, що й орфографічну проекцію, створіть відсічний коло, яке охоплює півсферу, яке буде видно в ортографічній проекції, і зафіксуйте формуляр з цим. Однак цей метод вимагає неабияких ручних зусиль і працює не для всіх параметрів проекції, оскільки проектування на азимутальну рівновіддалену проекцію може призвести до подібних проблем, як проеціювання до ортографічної проекції.
Ось сценарій (тепер також доступний як плагін QGIS Clip to Hemisphere ), який використовує дещо інший підхід: Відсічний шар створюється в системі координат оригінальної форми файлу шляхом проектування кола від ортографічного до вихідного CRS, але додатково обов'язково охоплюючи всю видиму півкулю, включаючи видимий полюс.
Ось так виглядає відсічний шар для ортографічної проекції, орієнтованої на 30 ° с.ш., 110 ° с.
Потім сценарій відсікає поточний вибраний шар із відсічним шаром і додає отриманий шар до проекту. Потім цей шар може бути спроектований на ортографічну проекцію як на льоту, так і за допомогою збереження в ортографічній CRS:
Ось сценарій. Обов’язково збережіть його у своєму шляху Python, наприклад, як "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)