Export Point Cloud Segmentations to KML Files
This example shows how to export segmented point cloud data to a Keyhole Markup Language (KML) file and read and visualize the KML data using different tools.
KML is an XML-based markup language designed for visualizing geographic data on web-based maps or Earth browsers, such as Google Earth™, Google Maps™, NASA WorldWind, and the Esri® ArcGIS™ Explorer. The KML international standard is maintained by the Open Geospatial Consortium, Inc. (OGC).
Load and Visualize Point Cloud Data
This example uses the point cloud data from the LAS file
aerialLidarData2.las, obtained from the Open Topography Dataset . Load the point cloud data into the workspace using the
readPointCloud function of the
lasFileReader object,and visualize the point cloud.
% Specify the LAS file path lasfile = fullfile(toolboxdir("lidar"),"lidardata","las", ... "aerialLidarData2.las"); % Create a lasFileReader object lasReader = lasFileReader(lasfile); % Read the point cloud ptCloud = readPointCloud(lasReader); % Visualize the point cloud figure pcshow(ptCloud) axis on title("Input Aerial Lidar Data")
Segment Point Cloud Data
This example segments the point cloud into buildings and vegetation by using a feature-based classification algorithm. First, perform ground segmentation by using the
segmentGroundSMRF function, and then classify the nonground points into vegetation and building by using the
helperSegment helper function.
% Segment the point cloud into ground and nonground points [~,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(ptCloud);
Segment the nonground point cloud into vegetation and buildings by using the
helperSegment helper function, defined at the end of this example.
% Segment the vegetation and buildings from the nonground point cloud labels = helperSegment(nonGroundPtCloud); % Compute the indices of the vegetation and building points in the point cloud vegetationIdx = labels == 1; buildingIdx = labels == 2;
Next, cluster the individual trees from the vegetation point cloud by using the
helperClusterVeg helper function, attached to this example as a supporting file.
% Extract the vegetation point cloud from the input point cloud vegPtCloud = select(ptCloud,vegetationIdx); % Specify the grid size (in meters per pixel) gridRes = 2; % Specify the minimum tree height (in meters) minTreeHeight = 5; % Cluster the individual trees from the segmented vegetation point cloud [validIds,vegClusterLabels] = helperClusterVeg(groundPtCloud, ... vegPtCloud,gridRes,minTreeHeight); % Create a logical array of the vegetation points in the clusters clusterVegetationIdx = vegetationIdx; vegetationInd = find(clusterVegetationIdx); clusterVegetationIdx(vegetationInd(~validIds)) = false;
Cluster the individual buildings from the building point cloud by using the
% Extract the building point cloud from the input point cloud buildingPtCloud = select(ptCloud,buildingIdx); % Cluster the individual buildings from the segmented building point cloud minDistance = 2; buildingClusterLabels = pcsegdist(buildingPtCloud,minDistance, ... NumClusterPoints=10);
Write Point Cloud Data to KML
To write point cloud data to a KML file, you must first convert the point cloud segmentations into real-world locations. This conversion requires a coordinate reference system (CRS). A CRS provides a framework for defining real-world locations. You can describe geographic data using these types of CRSs:
Geographic Coordinate Reference System — Provides information that assigns latitude, longitude, and height coordinates to real-world locations. A geographic CRS consists of a datum, a prime meridian, and an angular unit of measurement. To know more about geographic CRSs, see the
geocrs(Mapping Toolbox) object.
Projected Coordinate Refence System — Provides information that assigns Cartesian x- and y- coordinates to real-world locations. A projected CRS consists of a geographic CRS and several other parameters to transform coordinates to and from the geographic CRS. To know more about projected CRSs, see the
projcrs(Mapping Toolbox) object.
This example uses the projected CRS data from the LAS file to convert the point cloud segmentations to real-world locations. To check if the LAS file contains the projected CRS data, use the
hasCRSData function of the
Extract the projected CRS data from the LAS file using the
readCRS function of the
lasFileReader object. Then, extract the x- and y- coordinates of the point cloud segmentations. Use inverse projection with the projected CRS data to compute latitude and longitude data from these x- and y- coordinates. Write the point cloud data to a KML file by using the
kmlwritepoint (Mapping Toolbox) function.
% Read the CRS data projCRSData = readCRS(lasReader); % Convert the point cloud x- and y-coordinates to latitude and longitude [lat,lon] = projinv(projCRSData,ptCloud.Location(:,1), ... ptCloud.Location(:,2)); % Extract the heights of the points altitude = ptCloud.Location(:,3); % Write data to KML files kmlwritepoint("Building.kml",lat(buildingIdx),lon(buildingIdx), ... altitude(buildingIdx)); kmlwritepoint("Vegetation.kml",lat(vegetationIdx), ... lon(vegetationIdx),altitude(vegetationIdx));
Read KML Data
Read the Building.kml and Vegetation.kml files into the workspace as geospatial tables by using the
readgeotable (Mapping Toolbox) function.
% Read the KML files buildingKMLData = readgeotable("Building.kml"); vegetationKMLData = readgeotable("Vegetation.kml");
Visualize KML Data
There are several ways to visualize the KML data. In this example, you will visualize the data on a map, on a globe, and using RoadRunner.
On A Map
Visualize the data read from the KML files by using the
geoplot (Mapping Toolbox) function.
figure geoplot(buildingKMLData,MarkerEdgeColor="magenta") hold on geoplot(vegetationKMLData,MarkerEdgeColor="green") hold off geobasemap satellite legend("Building","Trees")
On A Globe
geoglobe (Mapping Toolbox) function, to visualize the data on a globe.
g = geoglobe(uifigure); geoplot3(g,buildingKMLData.Shape.Latitude,buildingKMLData.Shape.Longitude, ... altitude(buildingIdx),"mo") hold(g,"on") geoplot3(g,vegetationKMLData.Shape.Latitude,vegetationKMLData.Shape.Longitude, ... altitude(vegetationIdx),"go") hold(g,"off") % Set the camera height camheight(g,5*max(altitude))
To visualize the data using RoadRunner, you must first import the KML data into RoadRunner, using the Vector Data Tool. You can also add color to the KML data.
Follow these steps to import the
Building.kml file into RoadRunner.
1) Import the
Building.kml file into RoadRunner by using the Vector Data Tool.
2) Select the data you want to add color to.
3) In the Attributes pane, right-click Geometry Type, and select Color With.
4) Choose the color from the available options.
Repeat this process for the vegetation and visualize the results.
Note: You cannot write or access the color data of a KML file using RoadRunner. You must add colors every time you import the KML data into RoadRunner.
helperSegment helper function segments buildings and vegetation from a nonground point cloud. For more details on this workflow, see the Terrain Classification for Aerial Lidar Data example.
function labels = helperSegment(nonGroundPtCloud) % Specify the number of neighbors neighbors = 10; % Extract the normal and curvature features [normals,curvatures,neighInds] = helperExtractFeatures(nonGroundPtCloud, ... neighbors); % Specify the normal threshold and curvature threshold normalThresh = 0.75; curveThresh = 0.035; % Classify the point cloud into vegetation and buildings % Class | Label id % Vegetation | 1 % Building | 2 labels = helperClassify(normals,curvatures,neighInds, ... normalThresh,curveThresh); end
 Starr, Scott. "Tuscaloosa, AL: Seasonal Inundation Dynamics and Invertebrate Communities." National Center for Airborne Laser Mapping, December 1, 2011. OpenTopography. https://doi.org/10.5069/G9SF2T3K.