我在 QGIS 中运行了一个 Python 脚本。它看起来像这样:
class Ranker(object):
@staticmethod
def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
km = 6367 * c
return km
@staticmethod
def calculateDistance(featureProperty, layerEntrances):
if featureProperty.geometry() is None:
print("Null property geometry! Returning -1!")
return -1
shortestDistance = 1000
featuresEntrances = layerEntrances.getFeatures()
for featureEntrance in featuresEntrances:
if featureEntrance.geometry() is None:
print("Null entrance geometry! Skipping!")
continue
latEntrance = featureEntrance.geometry().centroid().asPoint().y()
lonEntrance = featureEntrance.geometry().centroid().asPoint().x()
latProperty = featureProperty.geometry().centroid().asPoint().y()
lonProperty = featureProperty.geometry().centroid().asPoint().x()
currentDistance = Ranker.haversine(lonEntrance, latEntrance, lonProperty, latProperty)
if currentDistance < shortestDistance:
shortestDistance = currentDistance
return shortestDistance
@staticmethod
def importAndAnalyze(rowLimit = 3):
layerProperties = iface.addVectorLayer("/Users/patrick/Downloads/DOR_Parcel/DOR_Parcel.shp", "Philly_City_Parcels", "ogr")
if not layerProperties:
print("layerProperties failed to load!")
layerEntrances = iface.addVectorLayer("/Users/patrick/Downloads/Stations/philly-rail-stations-merged.shp", "Rail_Stations", "ogr")
if not layerEntrances:
print("layerEntrances failed to load!")
features = layerProperties.getFeatures()
counter = 0
featuresSelected = []
Path('/Users/patrick/Desktop/philly-property-rankings.csv').touch()
with open('/Users/patrick/Desktop/philly-property-rankings.csv', 'a') as csvFile:
csvWriter = csv.writer(csvFile, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
csvWriter.writerow(['Address STD', 'Lat','Lon', 'Distance'])
for feature in features:
if counter < rowLimit:
csvWriter.writerow([feature['ADDR_STD'], feature.geometry().centroid().asPoint().y(),feature.geometry().centroid().asPoint().x(), Ranker.calculateDistance(feature, layerEntrances)])
if counter % 100 == 0:
csvFile.flush()
else:
break
counter += 1
csvFile.flush()
Ranker.importAndAnalyze(10000000)
问题是脚本处理了大约 57,000 行数据后,它会吐出这个错误:
Traceback (most recent call last):
File "/Applications/QGIS.app/Contents/MacOS/../Resources/python/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "<string>", line 72, in <module>
File "<string>", line 64, in importAndAnalyze
ValueError: Null geometry cannot be converted to a point.
我不明白这个错误是如何达到的。我的两个引用该None
值的条件不应该足以跳过任何空地理值吗?
完全披露:我通常不是 Python 人。如果我遗漏了一些明显的东西,请善待。