Questions on How to Create 1:1 Replicas of Real-Life Cities and Landscapes

I’m working on a project where I’m creating virtual environments based on real-world landscapes using GIS data. I’ve been tinkering around with the StreetMap plugin and the outcome looks great, however, I’m unable to apply a mesh to just the roads because the roads and the buildings seem to be imported as the same object.

  1. Is there any way to separate the roads the buildings so I can apply individual meshes? <– Solved
  2. If not, how would I go about applying a variety of meshes to the buildings so they’re not just one color or building type? <– Solved
  3. When I import a landscape with mountains, how would I snap the OSM data to the landscape or does it always just generate as a flat object as seen below?
  4. Is there a way to stop a static mesh from Z-fighting individual parts of itself? Could I accomplish this through blender or getting rid of the areas that overlap? How could I handle the “T” intersections?
  5. How would I fade out buildings once I’ve moved a fair distance away?
  6. How do I automate the process of creating Landscapes using heightmaps through Unreal’s Python API?
  7. How do I automatically change editor properties (Such as auto save and foliage) through Python?

Image of my current OSM data on a flat landscape:

Another image of how my Mesh remains flat on top of a landscape with heightmap data.

You can separate the data by feature type within any gis software.
no idea how the importer works, but the data is usually just that, data. You can sort and manage how you see fit…

I just separated the data into the roads and buildings through the JOSM application and re-imported it into the Unreal environment. It worked! Thank you so much for the suggestion.
The only issue I’m having now is that I can’t get both StreetMapActors to show up at once. Only the one I’ve highlighted will be visible (I can’t get the roads AND buildings to appear at the same time). Is there a setting I need to change in order for both of them to show up?

I’m not familiar at all with the plugin, but if you levarage the engine features you can probably bake an LOD of one or both StreetMapActors.

Assuming that works (can’t see why it shouldn’t) the process generates an engine made static mesh, so you can just eliminate the actor and place the mesh it generated into the level.

if you can do it with just one actor

(If you can’t, try adding an empty actor?)

And if that doesn’t work maybe this.

its more complicated, but you’ll probably have to get familiar with it anyway.

I did something similar to the documentations but with a small change. Turns out all I had to do was export the Actor into a static mesh before I could change the texture. What threw me off was that the plugin comes with an “Rebuild Mesh” option on an Actor whose textures can’t actually be changed. Thank you so much for the help!

I do have one more question though. On uneven landscapes, how would I snap the static meshes to the landscapes instead of it being completely flat? I’ve tried looking up how to do this but I don’t even know if it’s possible with this OSM data. From my knowledge I know that Splines are capable of doing this but I don’t know if that would work with my data.

Roads are generally better off as splines.
conforming them on a 1:1 terrain always requires adjustment. Also, for coding purposes you probably really want each road as a separate spline so that actors can be made to follow it.

Buildings are a different story.
Within the data from gis you probably have everything you need for all the verticis that make up the mesh of each building.
If the mesh gets generated you can add collision to it as complex.
This will allow you to hit the home key to have them automatically snap onto the terrain based on collision.
Once you have the general mesh you could aslo export it and split them off one by one, creating a more precise structure with unique meshes (thats where HLOD will come handy for performance).
Remeber to turn off complex collision if you do not need it after placement.

As a general rule of thumb, gis data or openstreetmap data is not accurate enough for a 1:1 scale map.
The heights are mostly all derived from 20m or even 30m DTM.
If you had a lidar reading at 1m you would get much more accurate/lifelike results.
Where the data is most inaccurate by nature is cliff faces and generally sharp changes in elevation. Anywhere that changes elevation in less than the size of the DTM, so 20m or 30m in lenght will probably be “off” when re-interpreted and scaled/adjusted.
So yes, there usually is a lot of manual labor involved, with the terrain, the roads, and the buildings…

I just tried setting the collision to complex on the Static Mesh and hit the home button but nothing happened. I’m assuming there’s other steps than I’m missing but for right now I’m not sure.

Edit: Here’s an image of my landscape as of right now. I would like the Static Mesh to snap to the landscape portion that slopes down but as mentioned earlier I don’t really know how to accomplish that.

I believe that the reason it isn’t working is that it is all one mesh.

A quick fix is to export in fbx.
Import in Blender.
enter edit mode.
A to select all
P and Separate by loose parts
Export back out to FBX, and import as separate parts.

More expensive renderinf wise, but you’ll be able to adjust each building’s height.

Afterwards you could use merge actors to go back to having only one mesh…

Oh wow Blender worked really smoothly. Thank you so much for your help.

The only thing I have with the process is that it’s a LOT of manual work. I’ve been looking into how BluePrints work and was wondering if I could use that to automate the process. Once I’ve separated the buildings into parts through Blender, could I import them into Unreal, assign the BluePrint to the Actors, and then push them to align with the Z-Coordinate of the Landscape?

Thread I read: https://answers.unrealengine.com/que…ap-static.html

Well, snapping to grid is not the same as detecting the underlying collision.

For that you would have to simulate physics.
And as you may imagine, should you simulate physics on a falling building, the building will likely Not fall straight down and stay where you need it to.

It would be easier to select all the actors for the buildings and just hit the home key.
For that to happen you have to generate collision upon import, or at worse, use the bulk edit by property matrix to enable complex collision on all the buildings.

Technically, because the way things are split in blender, all the buildings will have the same pivot point.
the idea there is that you can literally drag all the actors into a folder on the level and they will all place where they should be relative to the original pivot point (or blender’s 0,0,0).

If I’m correct, after dropping them in the level the buildings will already be pre-selected for you, so if they were imported with generated collision or you edited their properties you should be able to just press the home key and have them find the floor.

Its likely you will need to modify some of them or further drag them downwards if the terrain they are on is uneven. Just like with trees and foliage.

Aligning to the underlying surface would obviously tilt the building, so you need to avoid that.

Shader tricks prevent collision, so you can’t just flatten the mesh align to normal and extrude vertically if you need the collision to work and interact with the building(s).

The other alternarive is to export the lansacpe, place it in blender, and tailor the building location manually in edit mode to have it be more precise.
Obviously that’s a lot more work - even if it probably goes by faster then you would imagine, and provides better end results…

Ok I saw a lot of concern with the Physics part of the thread but I wasn’t sure if much of an issue that was. Thanks for clearing that up for me.

Your method was definitely a lot easier with the Complex Collision I had to use the “End” key instead of “Home” but otherwise a majority of the meshes stuck pretty perfectly to the landscape.

One of the last things I was struggling with was the Landscape Splines. Currently, I’m pulling data from OpenStreetMap and separating the Roads and Buildings (As you recommended earlier) in QGIS. I would then convert the .shp files I get from QGIS into .OSM files through JOSM. Finally, I dropped the files into Unreal which gives me the Buildings and Roads as Static Meshes. Is there any way I could convert the Static Meshes to Splines? Or, should I use the same strategy with the buildings?

I’ve found a plugin called TerraForm (LINK) which actually imports GIS road data as splines, but that takes data from a different site, not OpenStreetMap (I know it lists OSM data as an importable input but I haven’t figured out how to make it work just yet). Is there any way to accomplish this without using the plugin?

2 Likes

So, as I said many times. Data is data. So long as you have the data you can do anything with it.

In the case of splines you need a few mathematical operations to occur.

First.
I reccomend you extract just one road to start/test.
Also, as painful at it is each road should really be its own spline anyway.

With the extracted vertex data you need to output the longitude and latitude of the vertex that makenup the street.
you can do this by modyfying the properties and adding in the proper code.
google
x(transform($geometry, layer_property
it should bring you to a topic with the rest of the code - which I don’t remeber by hart.

Having extracted the data here you should probably (but it isnt required) get the Z position in there as well.
to do this you can look into the Point Sampling Tool plugin.

Having a generated dataset with x,y,and z, you can save a CSV file and work in Excel to produce the appropriate world bound coordinates.

Thats a bit of a topic on itself, but you map that got put into unreal is a slice of the DTM with a precise Extent.
the extent value in Qugis is in Lon/Lat notation - so you have to convert to unreal units to get the proper data in.

In essence you get the ratio of the extent vs unreal, and with that you calculate what a longitude/latitude coordinates actually mean within unreal.

Its fairly simple math mind you. Excel just… excels at allowing you to create a new sheet with only the data you need for export.

Once you get the print out, copy and past the values into a new Excel doc. Save as CSV, and import into the engine.

Then all you have to do is create a bluepring that modifies a selected spline by adding in the points.
I’m on mobile or I’d give you the link, but the base on how this is done is a 3 or 4 year old live training video. The system really hasn’t changed all that much.

running the blutility script you create based on that, you will generate the selected road spline.
use another blueprint that contains a spline btw, so that you can modify things like the mesh, or add a bluetility action to displace the terrain with this spline.

Assuming you did all of that with world Z, the points generated by the process should be more or less exact.
If they aren’t, you can right click one of the spline points, select all the spline controls, drag them up above the terrain and hit the End key to get them flat on the terrain (also why I said you could skip the world Z part).

Thats the gist of it.
Start with a small road with a max of 10 vertex to make sure that both the data calculations - which are easier to tell considering you already have buildings in place - are correct.
and that the generation scrip works as intended - since you will need to modify what the tutorial provides quite a bit.

To be more clean on the math.

Longitude - extent start = vertex X.

Ratio = Unreal World size / Extent X

Vertex X * Ratio = world coordinate in unreal units.

very basic.

Wow! Thank you so so much for going so in-depth on how to approach this. I greatly appreciate your help!!

I’ve been doing some research on how to use Blutility and I starting to understand how it works. although, I do have a couple quick questions in regards to the process.

  1. Does the math happen all within the BluePrint Utility code? From my understanding setting the splines should definitely happen in the Blutility code but does the conversion also occur in the same Blueprint?

  2. I am curious about the video you had mentioned and what it entails. Is it a tutorial on how to use Blutility with coordinate conversions specifically, or is it how to modify the splines? Or, is it general tutorial on how Blutility works? If you don’t mind finding that video it would be greatly appreciated.

EDIT: I found this video just after I posted (LINK). Is it something like that?

  1. no, the conversion should happen in Excel because its a lot easier.
    It can happen in engine if you really want it to, yet again, data being data you can always manipulate it.
    I just find it easier to use excel as it probably offers more precision.

  2. yes, thats the base video.
    it will give you nice pointers on how to handle the import.

And no, it doesn’t deal with the coordinates from qgis obviously. That’s just some ground work you have to put in on the math though…

So sorry to ask again but could you clarify a little about the step with the Point Sampling Tool. I don’t quite understand how it works.

Do I use the DEM and convert the Raster data to points? After that, would I then extract the Z values and put it into the .csv file of the road vectors?

the dtm is probably not 1m so the height values from it are best guess estimates.
The point sampling tool simply allows you to select a raster from which to pull elevation data.
If used on a list of points, it allows you to produce a final file with whatever custom information you want - you can select the fields to have in the data output.

Here is the site where I’m getting my data from I’ve been using a 1m DTM of New York City.

For some reason I can’t select the DTM from the dropdown list in the plugin. I tried converting the Raster using “Raster Values to Points” but QGIS just stops responding when I run it. Am I missing a step?

Well…
a 1m dtm of newyork is likely several thousand pixels in size. The process to extract the points may need some days of processing time - if it even can given the size of the raster is probably too much for 64GB of ram.

That said, right click the raster, choose save as, click the “render” option at the top and save it to the disk.
open a new project bring it in.
Add a single point in a vector layer, and try the tool again.

the issue could simply be that whatever raster you have now is not being detected as an actual raster. Hard to tell.

Also, do keep in mind this was not a necessary step if you got the map looking right in UE4 already.
You aren’t sampling historical height data since NYC isn’t even old enough to have been repaved. Its not like you need the original height of the appian way applied to the modern day map…
select all contol points and drag up, press Home. All points will snap to the terrain

Ah ok that probably explains why it’s taking so long. I haven’t had the chance to do a lot of testing beyond the basic Blutility scripting but I did run into some issues/questions.

  1. Snapping the Spline points to the terrain. I imported some of the test splines (from the old video) into my Unreal project and tried hitting the “End” key and “End + Shift” to snap it to the landscape. The Blutility actor did snap to the landscape, but the individuals points didn’t seem to follow the curvature of the landscape. By doing this, are each of the points supposed to have different Z-values or does the “End” key simply set the entirety of the actor to a specific Z-value? If the individual points do not snap, I may have to consider using the Point Sampling Tool for individual Z-values. (If you this does work on your computer/environment do you mind sending me a screenshot of how it looks)

  2. **What are ****Spline Tangent Points? **I’m a little confused on what these do especially because I don’t know how I would calculate them for each of my lines in the .shp file. From what I read I believe they determine the curvature of the spline from point to point but again I’m not sure. Do I necessary need these tangent points for a road or do I absolutely need to have them somewhere in my Blutility script for them to generate properly?