12 Dec work

This commit is contained in:
vinfamy 2017-12-13 03:52:18 +07:00
parent 199a62edfe
commit f2b56ede39
48 changed files with 241 additions and 122 deletions

View file

@ -43,6 +43,7 @@ DefaultViewportMouseLockMode=LockOnCapture
+ActionMappings=(ActionName="ActionX",Key=MouseX,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName="ActionY",Key=MouseY,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName="Pause",Key=SpaceBar,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName="SearchBarToggle",Key=F,bShift=False,bCtrl=True,bAlt=False,bCmd=False)
+AxisMappings=(AxisName="LeftRight",Key=Right,Scale=1.000000)
+AxisMappings=(AxisName="LeftRight",Key=Left,Scale=-1.000000)
+AxisMappings=(AxisName="DownUp",Key=Up,Scale=1.000000)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -390,6 +390,12 @@ bool FOSMFile::ProcessAttribute( const TCHAR* AttributeName, const TCHAR* Attrib
else if( !FCString::Stricmp( AttributeValue, TEXT( "fitness_centre" ) ) )
{
CurrentWayInfo->WayType = EOSMWayType::Building;
CurrentWayInfo->Amenity = AttributeValue;
}
else if( !FCString::Stricmp( AttributeValue, TEXT( "sports_centre" ) ) )
{
CurrentWayInfo->WayType = EOSMWayType::Building;
CurrentWayInfo->Amenity = AttributeValue;
}

View file

@ -82,6 +82,104 @@ bool UStreetMapFactory::LoadFromOpenStreetMapXMLFile( UStreetMap* StreetMap, FSt
(float)( ConvertLatitudeToMeters( Latitude ) - ConvertLatitudeToMeters( RelativeToLatitude ) ) );
};
// Adds a Park to the street map using the OpenStreetMap data, flattening the road's coordinates into our map's space
auto AddParkForWay = [ConvertLatLongToMetersRelative, OSMToCentimetersScaleFactor](
const FOSMFile& OSMFile,
UStreetMap& StreetMapRef,
const FOSMFile::FOSMWayInfo& OSMWay ) -> bool
{
if( OSMWay.WayType == FOSMFile::EOSMWayType::Park )
{
// Require at least three points so that we don't have degenerate polygon!
if( OSMWay.Nodes.Num() > 2 )
{
// Create a Park for this way
FStreetMapPark& NewPark = *new( StreetMapRef.Parks )FStreetMapPark();
FVector2D BoundsMin( TNumericLimits<float>::Max(), TNumericLimits<float>::Max() );
FVector2D BoundsMax( TNumericLimits<float>::Lowest(), TNumericLimits<float>::Lowest() );
NewPark.ParkPoints.AddUninitialized( OSMWay.Nodes.Num() );
int32 CurParkPoint = 0;
for( const FOSMFile::FOSMNodeInfo* OSMNodePtr : OSMWay.Nodes )
{
const FOSMFile::FOSMNodeInfo& OSMNode = *OSMNodePtr;
// Transform all points relative to the center of the latitude/longitude bounds, so that
// we get as much precision as possible.
const double RelativeToLatitude = OSMFile.AverageLatitude;
const double RelativeToLongitude = OSMFile.AverageLongitude;
const FVector2D NodePos = ConvertLatLongToMetersRelative(
OSMNode.Latitude,
OSMNode.Longitude,
RelativeToLatitude,
RelativeToLongitude ) * OSMToCentimetersScaleFactor;
// Update bounding box
{
if( NodePos.X < BoundsMin.X )
{
BoundsMin.X = NodePos.X;
}
if( NodePos.Y < BoundsMin.Y )
{
BoundsMin.Y = NodePos.Y;
}
if( NodePos.X > BoundsMax.X )
{
BoundsMax.X = NodePos.X;
}
if( NodePos.Y > BoundsMax.Y )
{
BoundsMax.Y = NodePos.Y;
}
}
// Fill in the points
NewPark.ParkPoints[ CurParkPoint++ ] = NodePos;
}
// Make sure the Park ended up with a closed polygon, then remove the final (redundant) point
const bool bIsClosed = NewPark.ParkPoints[ 0 ].Equals( NewPark.ParkPoints[ NewPark.ParkPoints.Num() - 1 ], KINDA_SMALL_NUMBER );
if( bIsClosed )
{
// Remove the final redundant point
NewPark.ParkPoints.Pop();
}
else
{
// Wasn't expecting to have an unclosed shape. Our tolerances might be off, or the data was malformed.
// Either way, it shouldn't be a problem as we'll close the shape ourselves below.
// @todo: Log this for the user as an import warning
}
NewPark.ParkName = OSMWay.Name;
if( NewPark.ParkName.IsEmpty() )
{
NewPark.ParkName = OSMWay.Ref;
}
NewPark.BoundsMin = BoundsMin;
NewPark.BoundsMax = BoundsMax;
StreetMapRef.BoundsMin.X = FMath::Min( StreetMapRef.BoundsMin.X, BoundsMin.X );
StreetMapRef.BoundsMin.Y = FMath::Min( StreetMapRef.BoundsMin.Y, BoundsMin.Y );
StreetMapRef.BoundsMax.X = FMath::Max( StreetMapRef.BoundsMax.X, BoundsMax.X );
StreetMapRef.BoundsMax.Y = FMath::Max( StreetMapRef.BoundsMax.Y, BoundsMax.Y );
return true;
}
else
{
// NOTE: Skipped adding Park for way because it has less than 3 points
// @todo: Log this for the user as an import warning
}
}
return false;
};
// Adds a road to the street map using the OpenStreetMap data, flattening the road's coordinates into our map's space
auto AddRoadForWay = [ConvertLatLongToMetersRelative, OSMToCentimetersScaleFactor](
const FOSMFile& OSMFile,
@ -318,7 +416,7 @@ bool UStreetMapFactory::LoadFromOpenStreetMapXMLFile( UStreetMap* StreetMap, FSt
};
/**
// Adds a water to the street map using the OpenStreetMap data, flattening the road's coordinates into our map's space
auto AddWaterForWay = [ConvertLatLongToMetersRelative, OSMToCentimetersScaleFactor](
const FOSMFile& OSMFile,
@ -417,104 +515,10 @@ bool UStreetMapFactory::LoadFromOpenStreetMapXMLFile( UStreetMap* StreetMap, FSt
return false;
};
*/
// Adds a Park to the street map using the OpenStreetMap data, flattening the road's coordinates into our map's space
auto AddParkForWay = [ConvertLatLongToMetersRelative, OSMToCentimetersScaleFactor](
const FOSMFile& OSMFile,
UStreetMap& StreetMapRef,
const FOSMFile::FOSMWayInfo& OSMWay ) -> bool
{
if( OSMWay.WayType == FOSMFile::EOSMWayType::Park )
{
// Require at least three points so that we don't have degenerate polygon!
if( OSMWay.Nodes.Num() > 2 )
{
// Create a Park for this way
FStreetMapPark& NewPark = *new( StreetMapRef.Parks )FStreetMapPark();
FVector2D BoundsMin( TNumericLimits<float>::Max(), TNumericLimits<float>::Max() );
FVector2D BoundsMax( TNumericLimits<float>::Lowest(), TNumericLimits<float>::Lowest() );
NewPark.ParkPoints.AddUninitialized( OSMWay.Nodes.Num() );
int32 CurParkPoint = 0;
for( const FOSMFile::FOSMNodeInfo* OSMNodePtr : OSMWay.Nodes )
{
const FOSMFile::FOSMNodeInfo& OSMNode = *OSMNodePtr;
// Transform all points relative to the center of the latitude/longitude bounds, so that
// we get as much precision as possible.
const double RelativeToLatitude = OSMFile.AverageLatitude;
const double RelativeToLongitude = OSMFile.AverageLongitude;
const FVector2D NodePos = ConvertLatLongToMetersRelative(
OSMNode.Latitude,
OSMNode.Longitude,
RelativeToLatitude,
RelativeToLongitude ) * OSMToCentimetersScaleFactor;
// Update bounding box
{
if( NodePos.X < BoundsMin.X )
{
BoundsMin.X = NodePos.X;
}
if( NodePos.Y < BoundsMin.Y )
{
BoundsMin.Y = NodePos.Y;
}
if( NodePos.X > BoundsMax.X )
{
BoundsMax.X = NodePos.X;
}
if( NodePos.Y > BoundsMax.Y )
{
BoundsMax.Y = NodePos.Y;
}
}
// Fill in the points
NewPark.ParkPoints[ CurParkPoint++ ] = NodePos;
}
// Make sure the Park ended up with a closed polygon, then remove the final (redundant) point
const bool bIsClosed = NewPark.ParkPoints[ 0 ].Equals( NewPark.ParkPoints[ NewPark.ParkPoints.Num() - 1 ], KINDA_SMALL_NUMBER );
if( bIsClosed )
{
// Remove the final redundant point
NewPark.ParkPoints.Pop();
}
else
{
// Wasn't expecting to have an unclosed shape. Our tolerances might be off, or the data was malformed.
// Either way, it shouldn't be a problem as we'll close the shape ourselves below.
// @todo: Log this for the user as an import warning
}
NewPark.ParkName = OSMWay.Name;
if( NewPark.ParkName.IsEmpty() )
{
NewPark.ParkName = OSMWay.Ref;
}
NewPark.BoundsMin = BoundsMin;
NewPark.BoundsMax = BoundsMax;
StreetMapRef.BoundsMin.X = FMath::Min( StreetMapRef.BoundsMin.X, BoundsMin.X );
StreetMapRef.BoundsMin.Y = FMath::Min( StreetMapRef.BoundsMin.Y, BoundsMin.Y );
StreetMapRef.BoundsMax.X = FMath::Max( StreetMapRef.BoundsMax.X, BoundsMax.X );
StreetMapRef.BoundsMax.Y = FMath::Max( StreetMapRef.BoundsMax.Y, BoundsMax.Y );
return true;
}
else
{
// NOTE: Skipped adding Park for way because it has less than 3 points
// @todo: Log this for the user as an import warning
}
}
return false;
};
@ -543,7 +547,15 @@ bool UStreetMapFactory::LoadFromOpenStreetMapXMLFile( UStreetMap* StreetMap, FSt
for( const FOSMFile::FOSMWayInfo* OSMWay : OSMFile.Ways )
{
// Handle buildings differently than roads
if( OSMWay->WayType == FOSMFile::EOSMWayType::Building )
if (OSMWay->WayType == FOSMFile::EOSMWayType::Park)
{
if (AddParkForWay(OSMFile, *StreetMap, *OSMWay))
{
// ...
}
}
else if( OSMWay->WayType == FOSMFile::EOSMWayType::Building )
{
if( AddBuildingForWay( OSMFile, *StreetMap, *OSMWay ) )
{
@ -552,7 +564,7 @@ bool UStreetMapFactory::LoadFromOpenStreetMapXMLFile( UStreetMap* StreetMap, FSt
}
/**
else if( OSMWay->WayType == FOSMFile::EOSMWayType::Water )
{
if( AddWaterForWay( OSMFile, *StreetMap, *OSMWay ) )
@ -560,14 +572,7 @@ bool UStreetMapFactory::LoadFromOpenStreetMapXMLFile( UStreetMap* StreetMap, FSt
// ...
}
}
else if( OSMWay->WayType == FOSMFile::EOSMWayType::Park )
{
if( AddParkForWay( OSMFile, *StreetMap, *OSMWay ) )
{
// ...
}
}
*/
else

View file

@ -77,6 +77,28 @@ bool FPolygonTools::IsPointInsidePolygon( const TArray<FVector2D>& Polygon, cons
return bIsInside;
}
/** Backup
bool FPolygonTools::IsPointInsidePolygon( const TArray<FVector2D>& Polygon, const FVector2D Point )
{
const int NumCorners = Polygon.Num();
int PreviousCornerIndex = NumCorners - 1;
bool bIsInside = false;
for( int CornerIndex = 0; CornerIndex < NumCorners; CornerIndex++ )
{
if( ( ( Polygon[ CornerIndex ].Y < Point.Y && Polygon[ PreviousCornerIndex ].Y >= Point.Y ) || ( Polygon[ PreviousCornerIndex ].Y < Point.Y && Polygon[ CornerIndex ].Y >= Point.Y ) ) &&
( Polygon[ CornerIndex ].X <= Point.X || Polygon[ PreviousCornerIndex ].X <= Point.X ) )
{
bIsInside ^= ( Polygon[ CornerIndex ].X + ( Point.Y - Polygon[ CornerIndex ].Y ) / ( Polygon[ PreviousCornerIndex ].Y - Polygon[ CornerIndex ].Y )*( Polygon[ PreviousCornerIndex ].X - Polygon[ CornerIndex ].X ) < Point.X );
}
PreviousCornerIndex = CornerIndex;
}
return bIsInside;
}
*/
bool FPolygonTools::Snip( const TArray<FVector2D>& Polygon, const int32 U, const int32 V, const int32 W, const int32 PointCount, const int32* VertexIndices )
{

View file

@ -2,7 +2,6 @@
#pragma once
#include "PolygonTools.h"
#include "StreetMap.generated.h"
@ -463,19 +462,15 @@ public:
/** Vinfamy added */
UFUNCTION(BlueprintCallable)
FStreetMapBuilding FindBuilding(const FVector2D Point)
{
FStreetMapBuilding emptyBuilding;
for (const auto &element : Buildings)
{
if (FPolygonTools::IsPointInsidePolygon(element.BuildingPoints, Point))
{
return element;
}
}
return emptyBuilding;
}
FStreetMapBuilding FindBuilding(const FVector2D Point);
UFUNCTION(BlueprintCallable)
TArray<FStreetMapBuilding> SearchByBuildingName(FString SearchTerm, FString Amenity) const;
UFUNCTION(BlueprintCallable)
TArray<FStreetMapBuilding> SearchByAmenity(FString Amenity) const;
TArray<FStreetMapBuilding> FilterByAmenity(FString Amenity, TArray<FStreetMapBuilding> SmallBuildings) const;
protected:

View file

@ -3,6 +3,10 @@
#include "StreetMapRuntime.h"
#include "StreetMap.h"
#include "EditorFramework/AssetImportData.h"
#include "PolygonTools.h"
#include "Runtime/Engine/Classes/Engine/StaticMesh.h"
#include "Runtime/Engine/Public/StaticMeshResources.h"
#include "PhysicsEngine/BodySetup.h"
UStreetMap::UStreetMap()
@ -27,3 +31,89 @@ void UStreetMap::GetAssetRegistryTags( TArray<FAssetRegistryTag>& OutTags ) cons
Super::GetAssetRegistryTags( OutTags );
}
FStreetMapBuilding UStreetMap::FindBuilding(const FVector2D Point)
{
FStreetMapBuilding emptyBuilding;
for (const auto &element : Buildings)
{
if (FPolygonTools::IsPointInsidePolygon(element.BuildingPoints, Point))
{
return element;
}
}
return emptyBuilding;
}
TArray<FStreetMapBuilding> UStreetMap::SearchByBuildingName(FString SearchTerm, FString Amenity) const
{
TArray<FStreetMapBuilding> Results;
if (SearchTerm.Len() > 0)
{
for (const auto &element : Buildings)
{
if (element.BuildingName.Contains(SearchTerm))
{
Results.Add(element);
}
}
}
else
{
Results = Buildings;
}
if (Amenity.Len() > 0)
{
Results = FilterByAmenity(Amenity, Results);
}
return Results;
}
TArray<FStreetMapBuilding> UStreetMap::SearchByAmenity(FString Amenity) const
{
TArray<FStreetMapBuilding> Results = FilterByAmenity(Amenity, Buildings);
return Results;
}
TArray<FStreetMapBuilding> UStreetMap::FilterByAmenity(FString Amenity, TArray<FStreetMapBuilding> SmallBuildings) const
{
TArray<FStreetMapBuilding> Results;
for (const auto &element : SmallBuildings)
{
if (element.Amenity == Amenity)
{
Results.Add(element);
}
else if (element.Building == Amenity)
{
Results.Add(element);
}
else if (Amenity == "residential")
{
if (element.Building == "apartments" || element.Building == "flats" || element.Building == "house")
{
Results.Add(element);
}
}
else if (Amenity == "office")
{
if (element.Building == "commercial" || element.Building == "tower")
{
Results.Add(element);
}
}
else if (Amenity == "sports_centre")
{
if (element.Amenity == "gym" || element.Building == "fitness_centre")
{
Results.Add(element);
}
}
}
return Results;
}