def testProfileRenderFixedColor(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) pcl.elevationProperties().setPointSymbol(Qgis.PointCloudSymbol.Square) pcl.elevationProperties().setPointColor(QColor(255, 0, 255)) pcl.elevationProperties().setPointSize(3) pcl.elevationProperties().setPointSizeUnit( QgsUnitTypes.RenderMillimeters) pcl.elevationProperties().setRespectLayerColors(False) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) plot_renderer = QgsProfilePlotRenderer([pcl], req) plot_renderer.startGeneration() plot_renderer.waitForFinished() res = plot_renderer.renderToImage(400, 400, 0, curve.length(), 2320, 2330) self.assertTrue( self.imageCheck('point_cloud_layer_fixed_color', 'point_cloud_layer_fixed_color', res))
def testRenderCrsTransform(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) renderer = QgsPointCloudClassifiedRenderer() renderer.setAttribute('Classification') layer.setRenderer(renderer) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:4326')) mapsettings.setExtent( QgsRectangle(152.980508492, -26.662023491, 152.980586020, -26.662071137)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName( 'expected_classified_render_crs_transform') result = renderchecker.runTest( 'expected_classified_render_crs_transform') TestQgsPointCloudClassifiedRenderer.report += renderchecker.report() self.assertTrue(result)
def testRenderFiltered(self): layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) categories = QgsPointCloudRendererRegistry.classificationAttributeCategories(layer) renderer = QgsPointCloudClassifiedRenderer('Classification', categories) layer.setRenderer(renderer) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) layer.setSubsetString('NumberOfReturns > 1') mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_classified_render_filtered') result = renderchecker.runTest('expected_classified_render_filtered') TestQgsPointCloudClassifiedRenderer.report += renderchecker.report() self.assertTrue(result) layer.setSubsetString('') renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_classified_render_unfiltered') result = renderchecker.runTest('expected_classified_render_unfiltered') TestQgsPointCloudClassifiedRenderer.report += renderchecker.report() self.assertTrue(result)
def testSetLayer16(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb16/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) # test that a point cloud with RGB attributes is automatically assigned the RGB renderer by default self.assertIsInstance(layer.renderer(), QgsPointCloudRgbRenderer) # for this point cloud, we should default to 0-65024 ranges with contrast enhancement self.assertEqual( layer.renderer().redContrastEnhancement().minimumValue(), 0) self.assertEqual( layer.renderer().redContrastEnhancement().maximumValue(), 65535.0) self.assertEqual( layer.renderer().redContrastEnhancement( ).contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchToMinimumMaximum) self.assertEqual( layer.renderer().greenContrastEnhancement().minimumValue(), 0) self.assertEqual( layer.renderer().greenContrastEnhancement().maximumValue(), 65535.0) self.assertEqual( layer.renderer().greenContrastEnhancement( ).contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchToMinimumMaximum) self.assertEqual( layer.renderer().blueContrastEnhancement().minimumValue(), 0) self.assertEqual( layer.renderer().blueContrastEnhancement().maximumValue(), 65535.0) self.assertEqual( layer.renderer().blueContrastEnhancement( ).contrastEnhancementAlgorithm(), QgsContrastEnhancement.StretchToMinimumMaximum)
def testRenderCrsTransform(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) renderer = QgsPointCloudExtentRenderer() renderer.fillSymbol().setColor(QColor(33, 140, 20)) layer.setRenderer(renderer) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:4326')) mapsettings.setExtent( QgsRectangle(152.980508492, -26.662023491, 152.980586020, -26.662071137).buffered(0.00001)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_extent_render_crs_transform') result = renderchecker.runTest('expected_extent_render_crs_transform') TestQgsPointCloudExtentRenderer.report += renderchecker.report() self.assertTrue(result)
def testRenderZRange(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent( QgsRectangle(497753.5, 7050887.5, 497754.6, 7050888.6)) mapsettings.setLayers([layer]) mapsettings.setZRange(QgsDoubleRange(1.1, 1.2)) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_zfilter') result = renderchecker.runTest('expected_zfilter') TestQgsPointCloudRgbRenderer.report += renderchecker.report() self.assertTrue(result)
def testRenderCrsTransform(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:4326')) mapsettings.setExtent( QgsRectangle(152.977434544, -26.663017454, 152.977424882, -26.663009624)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_rgb_render_crs_transform') result = renderchecker.runTest('expected_rgb_render_crs_transform') TestQgsPointCloudRgbRenderer.report += renderchecker.report() self.assertTrue(result)
def testRenderOrderedBottomToTop(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) renderer = QgsPointCloudClassifiedRenderer() renderer.setAttribute('Classification') layer.setRenderer(renderer) layer.renderer().setPointSize(6) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) layer.renderer().setDrawOrder2d( QgsPointCloudRenderer.DrawOrder.BottomToTop) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_classified_bottom_to_top') result = renderchecker.runTest('expected_classified_bottom_to_top') TestQgsPointCloudClassifiedRenderer.report += renderchecker.report() self.assertTrue(result)
def testMetadataClassStatistics(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) with self.assertRaises(ValueError): self.assertEqual( layer.dataProvider().metadataClassStatistic( 'X', 0, QgsStatisticalSummary.Count), []) with self.assertRaises(ValueError): self.assertEqual( layer.dataProvider().metadataClassStatistic( 'Classification', 0, QgsStatisticalSummary.Count), []) with self.assertRaises(ValueError): self.assertEqual( layer.dataProvider().metadataClassStatistic( 'Classification', 1, QgsStatisticalSummary.Sum), []) self.assertEqual( layer.dataProvider().metadataClassStatistic( 'Classification', 1, QgsStatisticalSummary.Count), 1) self.assertEqual( layer.dataProvider().metadataClassStatistic( 'Classification', 2, QgsStatisticalSummary.Count), 160) self.assertEqual( layer.dataProvider().metadataClassStatistic( 'Classification', 3, QgsStatisticalSummary.Count), 89) self.assertEqual( layer.dataProvider().metadataClassStatistic( 'Classification', 5, QgsStatisticalSummary.Count), 3)
def testRenderZRange(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) renderer = QgsPointCloudAttributeByRampRenderer() renderer.setAttribute('Intensity') renderer.setMinimum(200) renderer.setMaximum(1000) ramp = QgsStyle.defaultStyle().colorRamp("Viridis") shader = QgsColorRampShader(200, 1000, ramp) shader.classifyColorRamp() renderer.setColorRampShader(shader) layer.setRenderer(renderer) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999)) mapsettings.setLayers([layer]) mapsettings.setZRange(QgsDoubleRange(74.7, 75)) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_ramp_zfilter') result = renderchecker.runTest('expected_ramp_zfilter') TestQgsPointCloudAttributeByRampRenderer.report += renderchecker.report( ) self.assertTrue(result)
def testSetLayer(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) # test that a point cloud with RGB attributes is automatically assigned the RGB renderer by default self.assertIsInstance(layer.renderer(), QgsPointCloudRgbRenderer)
def testStatistics(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) self.assertEqual( layer.dataProvider().metadataStatistic( 'X', QgsStatisticalSummary.Count), 253) self.assertEqual( layer.dataProvider().metadataStatistic('X', QgsStatisticalSummary.Min), 498062.0) self.assertEqual( layer.dataProvider().metadataStatistic('X', QgsStatisticalSummary.Max), 498067.39) self.assertAlmostEqual( layer.dataProvider().metadataStatistic( 'X', QgsStatisticalSummary.Range), 5.39000000001397, 5) self.assertAlmostEqual( layer.dataProvider().metadataStatistic('X', QgsStatisticalSummary.Mean), 498064.7342292491, 5) self.assertAlmostEqual( layer.dataProvider().metadataStatistic( 'X', QgsStatisticalSummary.StDev), 1.5636647117681046, 5) with self.assertRaises(ValueError): layer.dataProvider().metadataStatistic( 'X', QgsStatisticalSummary.Majority) with self.assertRaises(ValueError): layer.dataProvider().metadataStatistic('Xxxxx', QgsStatisticalSummary.Count) self.assertEqual( layer.dataProvider().metadataStatistic( 'Intensity', QgsStatisticalSummary.Count), 253) self.assertEqual( layer.dataProvider().metadataStatistic('Intensity', QgsStatisticalSummary.Min), 199) self.assertEqual( layer.dataProvider().metadataStatistic('Intensity', QgsStatisticalSummary.Max), 2086.0) self.assertAlmostEqual( layer.dataProvider().metadataStatistic( 'Intensity', QgsStatisticalSummary.Range), 1887.0, 5) self.assertAlmostEqual( layer.dataProvider().metadataStatistic('Intensity', QgsStatisticalSummary.Mean), 728.521739130435, 5) self.assertAlmostEqual( layer.dataProvider().metadataStatistic( 'Intensity', QgsStatisticalSummary.StDev), 440.9652417017358, 5)
def testMetadataClasses(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) self.assertEqual(layer.dataProvider().metadataClasses('X'), []) self.assertCountEqual( layer.dataProvider().metadataClasses('Classification'), [1, 2, 3, 5])
def testSetLayer(self): layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/norgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) # test that a point cloud with no RGB attributes is automatically assigned the ramp renderer self.assertIsInstance(layer.renderer(), QgsPointCloudAttributeByRampRenderer) # check default range self.assertAlmostEqual(layer.renderer().minimum(), -1.98, 6) self.assertAlmostEqual(layer.renderer().maximum(), -1.92, 6)
def testSetLayer(self): layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) # test that a point cloud with RGB attributes is automatically assigned the RGB renderer by default self.assertIsInstance(layer.renderer(), QgsPointCloudRgbRenderer) # for this point cloud, we should default to 0-255 ranges (ie. no contrast enhancement) self.assertIsNone(layer.renderer().redContrastEnhancement()) self.assertIsNone(layer.renderer().greenContrastEnhancement()) self.assertIsNone(layer.renderer().blueContrastEnhancement())
def testSetLayer(self): m = QgsPointCloudAttributeModel() self.assertIsNone(m.layer()) layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) m.setLayer(layer) self.assertEqual(m.layer(), layer) self.assertEqual([a.name() for a in m.attributes().attributes()], [ 'X', 'Y', 'Z', 'Intensity', 'ReturnNumber', 'NumberOfReturns', 'ScanDirectionFlag', 'EdgeOfFlightLine', 'Classification', 'ScanAngleRank', 'UserData', 'PointSourceId', 'GpsTime', 'Red', 'Green', 'Blue' ])
def testSetLayer(self): cb = QgsPointCloudAttributeComboBox() self.assertIsNone(cb.layer()) layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/entwine/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) cb.setLayer(layer) self.assertEqual(cb.layer(), layer) self.assertEqual([cb.itemText(i) for i in range(cb.count())], [ 'X', 'Y', 'Z', 'Intensity', 'ReturnNumber', 'NumberOfReturns', 'ScanDirectionFlag', 'EdgeOfFlightLine', 'Classification', 'ScanAngleRank', 'UserData', 'PointSourceId', 'GpsTime', 'Red', 'Green', 'Blue' ])
def testRenderWithContrast(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) redce = QgsContrastEnhancement() redce.setMinimumValue(100) redce.setMaximumValue(120) redce.setContrastEnhancementAlgorithm( QgsContrastEnhancement.StretchToMinimumMaximum) layer.renderer().setRedContrastEnhancement(redce) greence = QgsContrastEnhancement() greence.setMinimumValue(130) greence.setMaximumValue(150) greence.setContrastEnhancementAlgorithm( QgsContrastEnhancement.StretchToMinimumMaximum) layer.renderer().setGreenContrastEnhancement(greence) bluece = QgsContrastEnhancement() bluece.setMinimumValue(170) bluece.setMaximumValue(190) bluece.setContrastEnhancementAlgorithm( QgsContrastEnhancement.StretchToMinimumMaximum) layer.renderer().setBlueContrastEnhancement(bluece) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent( QgsRectangle(497753.5, 7050887.5, 497754.6, 7050888.6)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_rgb_contrast') result = renderchecker.runTest('expected_rgb_contrast') TestQgsPointCloudRgbRenderer.report += renderchecker.report() self.assertTrue(result)
def testSnapping(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) generator = pcl.createProfileGenerator(req) generator.generateProfile(context) r = generator.takeResults() # try snapping some points context = QgsProfileSnapContext() res = r.snapPoint(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res.isValid()) context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 context.maximumSurfaceElevationDelta = 3 context.maximumSurfaceDistanceDelta = 1 res = r.snapPoint(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res.isValid()) context.maximumPointDistanceDelta = 1 context.maximumPointElevationDelta = 1 context.maximumSurfaceElevationDelta = 0 context.maximumSurfaceDistanceDelta = 0 res = r.snapPoint(QgsProfilePoint(0.27, 2335), context) self.assertTrue(res.isValid()) self.assertAlmostEqual(res.snappedPoint.distance(), 0.2783, 2) self.assertAlmostEqual(res.snappedPoint.elevation(), 2335.04575, 2)
def test_signals(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) props = layer.elevationProperties() spy = QSignalSpy(props.profileGenerationPropertyChanged) # when we are respecting layer colors, changing the 2d point cloud renderer should trigger a profile regeneration props.setRespectLayerColors(True) layer.setRenderer(QgsPointCloudClassifiedRenderer()) self.assertEqual(len(spy), 1) # when we aren't respecting layer colors, no signal should be emitted props.setRespectLayerColors(False) layer.setRenderer(QgsPointCloudClassifiedRenderer()) self.assertEqual(len(spy), 1)
def testRenderClipRegion(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:4326')) mapsettings.setExtent( QgsRectangle(152.977434544, -26.663017454, 152.977424882, -26.663009624)) mapsettings.setLayers([layer]) region = QgsMapClippingRegion( QgsGeometry.fromWkt( 'Polygon ((152.97742833685992991 -26.66301088198133584, 152.97742694456141521 -26.66301085776744983, 152.97742676295726483 -26.66301358182974468, 152.97742895431403554 -26.66301349708113833, 152.97742833685992991 -26.66301088198133584))' )) region.setFeatureClip( QgsMapClippingRegion.FeatureClippingType.ClipPainterOnly) region2 = QgsMapClippingRegion( QgsGeometry.fromWkt( 'Polygon ((152.97743215054714483 -26.66301111201326535, 152.97742715037946937 -26.66301116044103736, 152.97742754990858316 -26.66301436878107367, 152.97743264693181686 -26.66301491359353193, 152.97743215054714483 -26.66301111201326535))' )) region2.setFeatureClip( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) mapsettings.addClippingRegion(region) mapsettings.addClippingRegion(region2) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_clip_region') result = renderchecker.runTest('expected_clip_region') TestQgsPointCloudRgbRenderer.report += renderchecker.report() self.assertTrue(result)
def testRender(self): layer = QgsPointCloudLayer( unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) renderer = QgsPointCloudExtentRenderer() layer.setRenderer(renderer) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_extent_render') result = renderchecker.runTest('expected_extent_render') TestQgsPointCloudExtentRenderer.report += renderchecker.report() self.assertTrue(result)
def testProfileGeneration(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) # zero tolerance => no points generator = pcl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() self.assertFalse(results.distanceToHeightMap()) req.setTolerance(0.05) generator = pcl.createProfileGenerator(req) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 1), { 0.0: 2325.2, 0.2: 2332.6, 0.3: 2325.1, 0.6: 2331.4, 0.7: 2330.5, 0.9: 2332.7, 1.0: 2325.3, 1.1: 2325.6 }) print([g.asWkt(1) for g in results.asGeometries()]) self.assertCountEqual([g.asWkt(1) for g in results.asGeometries()], [ 'PointZ (515389.1 4918366.7 2326.1)', 'PointZ (515389.1 4918366.6 2325.6)', 'PointZ (515389 4918366.6 2325.3)', 'PointZ (515388.2 4918366.6 2325.2)', 'PointZ (515388.3 4918366.7 2325.1)', 'PointZ (515387.9 4918366.7 2325.2)', 'PointZ (515388.7 4918366.6 2330.5)', 'PointZ (515388.6 4918366.6 2331.2)', 'PointZ (515388.9 4918366.6 2332.7)', 'PointZ (515388.9 4918366.7 2332.7)', 'PointZ (515388.6 4918366.6 2331.4)', 'PointZ (515388.2 4918366.7 2332.2)', 'PointZ (515388.2 4918366.7 2332.6)', 'PointZ (515388.2 4918366.6 2335)', 'PointZ (515388.6 4918366.6 2334.6)' ]) self.assertAlmostEqual(results.zRange().lower(), 2325.1325, 2) self.assertAlmostEqual(results.zRange().upper(), 2335.04575, 2) # ensure maximum error is considered context.setMapUnitsPerDistancePixel(0.0001) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 2), { 0.0: 2325.17, 0.01: 2325.14, 0.02: 2325.18, 0.03: 2325.14, 0.08: 2325.16, 0.11: 2325.16, 0.12: 2325.14, 0.14: 2325.16, 0.15: 2325.14, 0.18: 2325.15, 0.19: 2325.15, 0.21: 2332.45, 0.22: 2332.68, 0.23: 2332.44, 0.24: 2332.38, 0.25: 2332.37, 0.26: 2325.16, 0.27: 2332.27, 0.28: 2335.05, 0.29: 2335.08, 0.3: 2334.71, 0.31: 2325.13, 0.32: 2325.14, 0.33: 2325.14, 0.34: 2325.13, 0.36: 2325.14, 0.39: 2325.14, 0.41: 2325.13, 0.42: 2325.14, 0.44: 2325.14, 0.46: 2325.14, 0.49: 2325.14, 0.53: 2325.14, 0.56: 2325.16, 0.57: 2325.16, 0.61: 2325.17, 0.62: 2331.38, 0.63: 2330.44, 0.64: 2331.31, 0.65: 2331.41, 0.66: 2331.33, 0.67: 2331.13, 0.68: 2331.14, 0.69: 2331.01, 0.7: 2331.0, 0.71: 2330.52, 0.72: 2330.61, 0.92: 2332.72, 1.0: 2325.29, 1.01: 2325.25, 1.02: 2325.27, 1.03: 2325.39, 1.04: 2325.36, 1.05: 2325.24, 1.07: 2325.41, 1.08: 2325.38, 1.09: 2325.23, 1.1: 2325.21, 1.11: 2325.3, 1.12: 2325.28, 1.13: 2325.24, 1.15: 2326.11, 1.16: 2325.22, 1.17: 2325.82, 1.18: 2325.49, 1.19: 2325.55, 1.2: 2325.58, 1.21: 2325.62 }) # ensure distance/elevation ranges are respected context.setDistanceRange(QgsDoubleRange(0.3, 0.7)) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 2), { 0.3: 2334.71, 0.31: 2325.13, 0.32: 2325.14, 0.33: 2325.14, 0.34: 2325.13, 0.36: 2325.14, 0.39: 2325.14, 0.41: 2325.13, 0.42: 2325.14, 0.44: 2325.14, 0.46: 2325.14, 0.49: 2325.14, 0.53: 2325.14, 0.56: 2325.16, 0.57: 2325.16, 0.61: 2325.17, 0.62: 2331.38, 0.63: 2330.44, 0.64: 2331.31, 0.65: 2331.41, 0.66: 2331.33, 0.67: 2331.13, 0.68: 2331.14, 0.69: 2331.01, 0.7: 2330.97 }) context.setElevationRange(QgsDoubleRange(2325, 2326)) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 2), { 0.31: 2325.13, 0.32: 2325.14, 0.33: 2325.14, 0.34: 2325.13, 0.36: 2325.14, 0.39: 2325.14, 0.41: 2325.13, 0.42: 2325.14, 0.44: 2325.14, 0.46: 2325.14, 0.49: 2325.14, 0.53: 2325.14, 0.56: 2325.16, 0.57: 2325.16, 0.61: 2325.17, 0.64: 2325.18, 0.68: 2325.19 })
def testIdentify(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) generator = pcl.createProfileGenerator(req) generator.generateProfile(context) r = generator.takeResults() # try identifying some points context = QgsProfileIdentifyContext() context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res) context.maximumPointDistanceDelta = 1 context.maximumPointElevationDelta = 1 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 199, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.60825, 'Y': 4918366.628, 'Z': 2334.60175 }]) context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsDoubleRange(0.2, 0.3), QgsDoubleRange(2330, 2360), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertCountEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 565, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.21275, 'Y': 4918366.65675, 'Z': 2332.19075 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1357, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17375, 'Y': 4918366.679, 'Z': 2332.56025 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }])
def testIdentify(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) generator = pcl.createProfileGenerator(req) generator.generateProfile(context) r = generator.takeResults() # try identifying some points context = QgsProfileIdentifyContext() context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res) context.maximumPointDistanceDelta = 1 context.maximumPointElevationDelta = 1 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertCountEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 199, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.60825, 'Y': 4918366.628, 'Z': 2334.60175 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1678, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.27575, 'Y': 4918366.6325, 'Z': 2334.728 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1605, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.25025, 'Y': 4918366.62825, 'Z': 2334.7095 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1633, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.28575, 'Y': 4918366.66725, 'Z': 2334.7065 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1547, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.238, 'Y': 4918366.6555, 'Z': 2335.0755 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1603, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.26675, 'Y': 4918366.685, 'Z': 2334.69125 }]) context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsDoubleRange(0.2, 0.3), QgsDoubleRange(2330, 2360), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertCountEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 565, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.21275, 'Y': 4918366.65675, 'Z': 2332.19075 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1357, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17375, 'Y': 4918366.679, 'Z': 2332.56025 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1452, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1985, 'Y': 4918366.61025, 'Z': 2332.38325 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 501, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2145, 'Y': 4918366.66275, 'Z': 2332.16675 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1197, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.22125, 'Y': 4918366.68675, 'Z': 2332.2715 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 202, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.16825, 'Y': 4918366.6625, 'Z': 2332.73325 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 922, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.165, 'Y': 4918366.65025, 'Z': 2332.6565 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 955, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1715, 'Y': 4918366.673, 'Z': 2332.6835 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1195, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1785, 'Y': 4918366.6955, 'Z': 2332.6125 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1432, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.15825, 'Y': 4918366.62575, 'Z': 2332.501 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1413, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1615, 'Y': 4918366.63675, 'Z': 2332.453 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1547, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.238, 'Y': 4918366.6555, 'Z': 2335.0755 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1259, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.20925, 'Y': 4918366.646, 'Z': 2332.29025 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1369, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1895, 'Y': 4918366.662, 'Z': 2332.38325 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1394, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2015, 'Y': 4918366.703, 'Z': 2332.36625 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 688, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.166, 'Y': 4918366.654, 'Z': 2332.7065 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1399, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17225, 'Y': 4918366.60575, 'Z': 2332.57475 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1024, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17475, 'Y': 4918366.683, 'Z': 2332.636 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1274, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1585, 'Y': 4918366.62625, 'Z': 2332.5265 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1443, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.15875, 'Y': 4918366.62725, 'Z': 2332.4765 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1332, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.18, 'Y': 4918366.69875, 'Z': 2332.43775 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1295, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1725, 'Y': 4918366.67475, 'Z': 2332.5855 }])