ArcGIS Maps SDK for Unreal Engine demo

ArcGIS Maps SDK for Unreal Engine demo

插件主要分为两部分:ArcGIS数据API接口和UE4渲染部分。

UArcGISRendererComponent继承自AActor,包含以下对象:
ArcGISRendererView 负责组织数据源map,更新位置camera,坐标转换coords。
SceneComponentProvider :有地图数据动态生成Mesh组件,并挂载到UArcGISRendererComponent下。
GPUResourcesProvider : 材质资源的生成。
NormalMapGenerator :法向量。
TextureComposer :纹理混合。
Matrix :CoordinateSystem
FArcGISRenderer: 实际渲染的实现。

void UArcGISRendererComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	if (RendererView)
	{
		//准备相关渲染处理函数
		if (!ArcGISRenderer)
		{
			//GPU资源相关处理
			GPUResourcesProvider = std::make_shared<FGPUResourcesProvider>();
			
			//Mesh资源相关处理
			SceneComponentProvider = std::make_shared<FSceneComponentProvider>(this);
			//纹理资源相关处理
			TextureComposer = std::make_shared<FTextureComposer>(this, GPUResourcesProvider);
			//法线向量相关处理
			NormalMapGenerator = std::make_shared<FNormalMapGenerator>(this, GPUResourcesProvider);
			//生成渲染对象
			ArcGISRenderer =
				Esri::MakeShared<Esri::ArcGISMapsSDKLib::FArcGISRenderer>(RendererView, GPUResourcesProvider->GetFunctions(), SceneComponentProvider->GetFunctions(),
												  TextureComposer->GetFunctions(), NormalMapGenerator->GetFunctions());

			CoordinateSystem = RendererView->GetCoordinateSystem();
			RepositionAllActors(CoordinateSystem);
		}
		//每一帧渲染,开始渲染
		ArcGISRenderer->Tick(DeltaTime);

		UpdateCoordinateSystem();
	}
}

示例

  • Create the map document
  • Add a basemap
  • Set the basemap
  • Set the elevation
  • Create other layers
  • Create extent
  • Create a camera
  • Create the renderer view and set it the camera and the map
  • Set the renderer view to the renderer component
  • Create our sample pawn
  • Assign renderview to the current main camera component
  • Add reposition components to the directional and sky lights
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"

#include "Components/ArcGISRendererComponent.h"

#include "SampleAPIMapCreator.generated.h"

// The declaration of our Actor class
UCLASS()
class ARCGISSAMPLES_API ASampleAPIMapCreator : public AActor
{
	GENERATED_BODY()

public:
	ASampleAPIMapCreator();

protected:
	virtual void BeginPlay() override;

private:
	UArcGISRendererComponent* ArcGISRendererComponent;

	void CreateArcGISMap();
};
#include "SampleAPIMapCreator.h"

#include "Components/DirectionalLightComponent.h"
#include "Components/SkyLightComponent.h"
#include "Engine/DirectionalLight.h"
#include "Engine/SkyLight.h"
#include "Engine/World.h"
#include "Kismet/GameplayStatics.h"

#include "ArcGISMapsSDKLib/API/GameEngine/Camera/ArcGISCamera.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGIS3DModelLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGISBasemapLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGISElevationLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGISImageLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/ArcGISMap.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/ArcGISMapElevation.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/ArcGISMapType.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/Extent/ArcGISMapExtentRectangle.h"
#include "ArcGISMapsSDKLib/API/Unreal/Collection.h"

#include "Components/ArcGISDirectionalLightRepositionComponent.h"
#include "Components/ArcGISSkyLightRepositionComponent.h"

#include "Math/Convert.h"
#include "SampleDefaultPawn.h"

ASampleAPIMapCreator::ASampleAPIMapCreator()
{
	PrimaryActorTick.bCanEverTick = false;
	//生成渲染组件
	ArcGISRendererComponent = CreateDefaultSubobject<UArcGISRendererComponent>(TEXT("ArcGISRendererComponent"));
	AddOwnedComponent(ArcGISRendererComponent);
}

void ASampleAPIMapCreator::BeginPlay()
{
	Super::BeginPlay();
	CreateArcGISMap();
}

// We create our map with this method
void ASampleAPIMapCreator::CreateArcGISMap()
{
	// API Key
	constexpr auto apiKey = ""; // 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b";

	// Create the map document
	auto mapType = Esri::GameEngine::Map::ArcGISMapType::Global;
	auto arcGISMap = Esri::MakeShared<Esri::GameEngine::Map::ArcGISMap>(mapType);

	// Add a basemap
	auto arcGISBasemapLayer = Esri::GameEngine::Layers::ArcGISBasemapLayer(
		"https://www.arcgis.com/sharing/rest/content/items/716b600dbbac433faa4bec9220c76b3a/data", apiKey);

	// Set the basemap
	arcGISMap->SetBasemapLayer(arcGISBasemapLayer);

	// Set the elevation
	auto elevationLayer = Esri::GameEngine::Layers::ArcGISElevationLayer(
		"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer", "Elevation", apiKey);
	arcGISMap->SetElevation(elevationLayer);

	// Create layers
	auto layer_1 = Esri::GameEngine::Layers::ArcGISImageLayer(
		"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/UrbanObservatory_NYC_TransitFrequency/MapServer", "MyLayer_1", 1.0f,
		true, apiKey);
	arcGISMap->GetLayers().Add(layer_1);

	auto layer_2 = Esri::GameEngine::Layers::ArcGISImageLayer(
		"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Industrial/MapServer", "MyLayer_2", 1.0f, true, apiKey);
	arcGISMap->GetLayers().Add(layer_2);

	auto layer_3 = Esri::GameEngine::Layers::ArcGISImageLayer(
		"https://tiles.arcgis.com/tiles/4yjifSiIG17X0gW4/arcgis/rest/services/NewYorkCity_PopDensity/MapServer", "MyLayer_3", 1.0f, true, apiKey);
	arcGISMap->GetLayers().Add(layer_3);

	auto layer_4 = Esri::GameEngine::Layers::ArcGIS3DModelLayer(
		"https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Buildings_NewYork_17/SceneServer", "MyLayer_4", 1.0f, true, apiKey);
	arcGISMap->GetLayers().Add(layer_4);

	// Remove a layer
	auto index = arcGISMap->GetLayers().IndexOf(layer_3);
	arcGISMap->GetLayers().Remove(index);

	// Update properties
	layer_1.SetOpacity(0.9f);
	layer_2.SetOpacity(0.6f);
	layer_4.SetOpacity(1.0f);

	// Create extent
	if (mapType == Esri::GameEngine::Map::ArcGISMapType::Local)
	{
		auto extentCenter = Esri::GameEngine::Location::ArcGISGlobalCoordinatesPosition(40.691242, -74.054921, 3000);
		auto extent = Esri::GameEngine::Map::Extent::ArcGISMapExtentRectangle(extentCenter, 10000, 10000);
		arcGISMap->SetExtent(extent);
	}

	String name("Camera_1");
	Esri::GameEngine::Location::ArcGISRotation orientation(68, 0, 65);
	Esri::GameEngine::Location::ArcGISGlobalCoordinatesPosition position(40.691242, -74.054921, 3000);

	// Create a camera
	auto arcGISCamera = Esri::MakeShared<Esri::GameEngine::Camera::ArcGISCamera>(name, position, orientation);

	// Create the renderer view and set it the camera and the map
	auto rendererView = Esri::MakeShared<Esri::GameEngine::View::ArcGISRendererView>();

	rendererView->SetMap(arcGISMap);
	rendererView->SetCamera(arcGISCamera);

	// Set the renderer view to the renderer component
	ArcGISRendererComponent->RendererView = rendererView;

	// Create our sample pawn
	ASampleDefaultPawn* arcGISPawn = GetWorld()->SpawnActor<ASampleDefaultPawn>();

	// ASSIGN RENDERERVIEW TO THE CURRENT MAIN CAMERA COMPONENT
	auto cameraComponent = arcGISPawn->FindComponentByClass<UArcGISCameraComponent>();
	cameraComponent->RendererView = rendererView;

	arcGISPawn->SetActorLocationAndRotation(Convert::ToFVector(rendererView->GetCameraLocalPosition()),
											Convert::ToFQuat(rendererView->GetCameraLocalRotation()));

	// Add reposition components to the directional and sky lights
	auto directionalLightActor = UGameplayStatics::GetActorOfClass(GetWorld(), ADirectionalLight::StaticClass());
	auto skyLightActor = UGameplayStatics::GetActorOfClass(GetWorld(), ASkyLight::StaticClass());

	if (directionalLightActor)
	{
		auto directionalLightReposition = NewObject<UArcGISDirectionalLightRepositionComponent>(
			directionalLightActor, UArcGISDirectionalLightRepositionComponent::StaticClass(), NAME_None, RF_Transient);
		directionalLightReposition->RendererView = rendererView;
		directionalLightReposition->RegisterComponent();
	}

	if (skyLightActor)
	{
		auto lightReposition =
			NewObject<UArcGISSkyLightRepositionComponent>(skyLightActor, UArcGISSkyLightRepositionComponent::StaticClass(), NAME_None, RF_Transient);
		lightReposition->RendererView = rendererView;
		lightReposition->RegisterComponent();
	}
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值