LandscapeEditorUtils::SetHeightmapData

I had code a perlin noise terrain generate function refer to a book.
The example has use the LandscapeEditorUtils::SetHeightmapData function to recreate terrain haight.
If it’s ok, return true.
I use it, and the result is true.
But, landscape has nothing to change.
I wonder why the problem. Thanks a lot.

here the code:

// MUST CALL.
	ULandscapeInfo::RecreateLandscapeInfo(GetWorld(), 1);

	// Get all the landscapes in the level.
	TArray<ALandscape*> landscapes = GetLandscapes();

	// Go thru all landscape objects..
	for (ALandscape* landscape : landscapes)
	{
		FIntRect rect = landscape->GetBoundingRect();
		// LandscapeEditorUtils::SetHeightmapData adds one to each dimension
		// because the boundary edges may be used.
		int32 cols = rect.Width() + 1, rows = rect.Height() + 1;
		int32 numHeights = cols * rows;
		//Info(FS("LANDSCAPE `%s` measures %dx%d has %d elts",
		//	*landscape->GetName(), rows, cols, numHeights));

		UE_LOG(LogTemp, Warning, TEXT("Landscape gogogogoogogogo"));

		TArray<uint16> Data;
		Data.Init(0, numHeights);

		// #octaves to sum, period in x, period in y.
		// The larger the period, the more variation we get
		// in the lowest frequency.
		int32 octaves = 16, px = 4, py = 4;
		float amplitude = 1000.f;
		for (int i = 0; i < Data.Num(); i++)
		{
			float nx = (i % cols) / (float)cols; //normalized col
			float ny = (i / cols) / (float)rows; //normalized row
			Data[i] = PerlinNoise2D(nx, ny, amplitude, octaves, px, py);

			//UE_LOG(LogTemp, Warning, TEXT("The Data: %d"), Data[i]);
		}

		bool isSuccessed = LandscapeEditorUtils::SetHeightmapData(landscape, Data);
		UE_LOG(LogTemp, Warning, TEXT("is Successed:%s"), isSuccessed?TEXT("Ture"):TEXT("False"));
		ULandscapeInfo::RecreateLandscapeInfo(GetWorld(), 1);

		// resample to ensure it works
		//LandscapeEditorUtils::ResampleData<uint16>( Data, cols, rows, cols, rows );

		
	} // each landscape