mapzengo pokemongo unity3d pois places

MapzenGo Part 8 : Places and Pois

It has been like… just two weeks? Oh boy that felt sooo much longer, rough days…

I just realized that I have to blog now and can’t run away from it anymore. It’s soo much harder than coding really. After all these years and so many posts, I still feel horrible at blogging and incredible nervous while writing…  But anyway, I have lots of new stuff, two new layers, no wait three even; earth, places and pois, this time! New and better triangulation library, improved settings window, brand new UI visualization and lots of bug fixes. So let’s have a look;

-Let’s start small, well I added the earth layer… just because. It’s just a clone of landuse and water layers really, nothing interesting here. Admittedly I hardly even tested it. I believe it’s coming from Natural Earth api, remember Mapzen is OpenStreetMap + Natural Earth. It has some interesting features like cliff, ridge, valley but well, I’ve always been much more interested in cities so personally didn’t find it that useful.

-No worries, I have something better; places and poi (Point of interest) layers!
Places layers is like a list of populated places; cities, towns, neighbourhoods etc. It’s extremely useful for city/state/country names at low zoom levels and neighborhood names in high zoom levels.  It looks great coupled with boundary layer as well.
Poi level is even more interesting, it’s a huge list of…. interesting points… yeah. It has lots of places like Apple Store, H&M, Walgreens categorized under so many different “types”. You can check the Mapzen documentation, it’s quite detailed and explains many new properties very well.

mapzengo pois places pokemongo unity3d labelsCity and neighbourhood labels

One important thing to note here though, both these layers use the screen space UI and not the 3D world like the others. Why? Well I initially created 3D markers, like pokestops in PokemonGo but they were extremely hard to use (overlapping with each other) and understand. And you probably already know how horrible is the Unity3D  TextMesh component is. I also tried using icons on a billboard but sprites looked blurry and low quality as well. Instead I put an empty gameobject in the 3D world (as a marker) and an icon on UI which sticks to that empty gameobject on every update. It looks a lot better this way, easier to read text/icons and interact with them. If you want 3D objects though, you can still use those empty gameobject as well!

mapzen go pois place manhattan pokemongo unity3dUI elements on pois

-OK what else? Hmm hmm hmm… Ah the UV mappings!  I won’t go into too much detail with these as it’s tiny little bit complex and hard to explain but we have UVs now. Roads, landscape and water UV mapping was quite easy with repetitive textures really. Building UV mapping is a little harder and not really complete but if you’re interested, you can read our little discussion about it in this Github issue.  You can see roads, park and building UVs in the image below.

mapzen pois places uv mapping pokemongo unity3dMapzenGo with “First-result-on-google” textures

-By the way, you probably noticed how almost every screenshot has a different style right? It’s all just tweaking settings and materials, I’m not keeping any code from you guys. You can achieve all those in like 5-10 minutes of work (after you have a grasp on the general structure). For example, I got bored a few nights ago and created this PokemonGo style in a few minutes; with roads, buildings and pokemons!
That being said, I’m well aware that it’s also quite hard to switch between styles and this is I’m planning to look into soon as well and you’ll probably be able to drag&drop different styles after that.

There are probably bunch of other stuff I’m forgetting at the moment but it’s getting late, I’m getting tired so I’ll just cut it here.

mapzengo pokemongo unity3d pois placesManhattan after 50 post process image effects

What’s next? Well I want to restructure the folder hierarchy first. Not sure exactly about this one yet but I want to switch to factory/layer focused hierarchy where everything related to a single layer rests under one folder. That way it’ll be easier to plug in/out layers into any project.

Then I want a slightly different factory/settings management system. Roman’s (kind gentlemen who wrote all the settings scripts) gonna kill me , I know but I have…some ideas. Yea that sounds bad… I just want to make it easier to use, plug stuff in/out, tweak, change styles etc etc. Unfortunately I’m horrible at editor scripts so might not be able to do this for a while.

Then maybe some improvements for the UI icons of poi and places layers. Or some road mesh improvements (smoother curves? pavements?) Oh and I’m planning to drop/change the running guy thing as it takes like the 90% of the package size. And he’s not even that handsome.

Anyway so yeah, I’ll keep working on it as much as I can. Please do keep posting me… whatever. I just love hearing from you guys. That’s pretty much what keeps me going.

Cheers,
Baran

MapzenGo Github Page
Twitter
Download MapzenGo Part 8
(v8.1 @5.10.2016, removed unnecessary image effects folder)
(v8.2 @5.10.2016, fixed BasicLoader and DynamicLoader scenes)
(v8.3 @5.10.2016, fixed some default values and settings for Poi factory)
(v8.4 @15.10.2016, Mapzen Api v1 compatibility)
(v8.5 @28.10.2016, fixed a small bug where scriptable object doesn’t run in non-windows platforms)

Save

Save

Save

unity_2016-09-11_22-27-54

MapzenGo Part 7 : Plugins

Well yes, I decided to change the name of the series to simply “MapzenGo”. It’s shorter and admittedly, “PokemonGo clone” was a bit of a click bait. But hey, advertisement eh??
Anyway, we have another big update here. Mainly infrastructure stuff but I think you’ll all find them useful.

mapzen pokemongo openstreetmap layers offline maps buildings tokyoGood old Manhattan

-Major thing here is the new plugin system. Well I changed the factories a bit…again but nothing big really. First of all, I introduced a new base class called “Plugin”. It has a simple “Create” function and will be used for both factories and additional… plugins. So plugins are classes which operates on Tiles. Simple as that. Factories take tiles and creates buildings, roads etc. Other plugins, takes tiles and puts map images on them, add custom objects, maybe create forests or something.

So now you can create a class, inherit it from plugin, fill up the create method and put it under the World object in the scene. It’ll work right away.
That being said, I’m not done with refactoring the factories yet, I’ll remove the create from base factory class and leave that part to sub classes as well. That won’t effect the plugin system though, you’ll be able to work on your own plugins unaffected.

-Then I implement as very simple CustomObjectPlugin. People has been asking about how to visualized their own custom locations for weeks now. And yes it wasn’t really straight forward how to convert lat/long to unity3d position but this new plugin should help you with that. It’s just a sample really, nothing fancy going on there and you’ll probably need something much more complex for your needs but this should be enough to get you started.

-Then there is a great editor script, written by Roman (thanks mate!), to search places and use their lat/long right away. Admittedly I haven’t checked the code in detail but it uses Mapzen search api to find places, retrieve their lat/long and pass it to the tile manager. It’s so much easier now to navigate between different places, be it Manhatta, Paris or Istanbul.

mapzen pokemongo openstreetmap layers offline maps buildings tokyo search mapzengoSo much easier to test different place now.

-And I also fixed namespaces to match file locations. Should have done this much earlier, no idea how I missed it.

-Oh wait I actually forgot the biggest thing, entity settings and filtering! Well I did talked about this a little in previous posts but extended it a lot since then.
Ok, what is it? Remember, we didn’t have much chance to customize stuff before; hust some hard coded materials which wasn’t enough for anything really. No chance to set road widths, materials by building type etc.
So we have a new settings system to fix that! If you check the factory objects in the scene, you’ll see that there is a new Settings list under it. Using that list, you can customize, let’s say highway roads width or religious buildings material.

Even better, some factories (not all) are using those settings to filter entities, i.e. Road factory won’t render “ferry” routes if you don’t have a settings for that! This saves us from all the mess in big cities and helps us get a cleaner look. If I recall correctly, only building factory doesn’t use this filtering method. Building factory will render every single building and use custom settings on selected typed buildings.
We have only a few customization properties for now but it’s quite easy to add anything whenever we need. Ah and Roman is also working on moving all those settings to ScriptableObjects, it’ll get much easier to use as well.

mapzen pokemongo openstreetmap layers offline maps buildings stockholmStockholm

And that’s all for now I guess. I’ll try to look into gps, UV maps and other stuff next few weeks, no promises though, day job is getting quite intense these days.

Let me know what you think! You can mail me, post here or create issues on MapzenGo Github page. I also added a donation button at the right column (and at the bottom of this post), consider that as buying me a coffee or a beer. Oh I can definitely use a weihenstephaner right now…

Cheers,
Baran

MapzenGo Github Page
Twitter (started posting beauty shots and whatever there)
Download MapzenGo Part 7: Plugins

Save

mapzen pokemongo openstreetmap layers offline maps buildings tokyo

PokemonGo clone using Mapzen – Part 6: Offline Maps

Yes, I’m back with offline maps this time! (I’ll say it right away, it’s still a work in progress and have issues)
This was one of the most requested features since the last post and I decided to give it a shot. I have some other improvements&fixes as well but let’s do it in bullet style again, it’s so much easier for me that way.

-Offline Maps; well yes the big thing is the offline maps this time. Admittedly I just did a simple basic implementation for now, as it’s a huge topic itself, didn’t had time to do a complex complete implementation. Anyway, how it works; first of all, all you need is to use “CachedDynamicLoader”. That’s all. This script has a simple caching system; every time it needs to load a tile, it first checks if it exists in a predefined folder. If it’s there, it just loads the file and reads the Mapzen data from that, if not it requests the data from Mapzen api and then saves it in that folder for later usage.

Want to test it? You should run the “CachedDynamicLoader” scene and run around a bit. In this initial run, there will be nothing cached so it’ll load everything from server BUT it’ll also save them as a file. Notice how long it takes to load single tile. Now restart the game, you can even unplug your internet connection at this point, and this time, it’ll load everything from file system, much much faster.

But be careful, there is a little unsolved (for now) issue here; it takes so little time to load data from file so it’ll try to load and create all tiles at once, which will most likely freeze the editor. I’ll look into this in the future, for now try to stick with range 1 or something small like that. So yea, it’s far from done for now but it’ll only get better. It’s on this update so that you can work on it as you want as well.

mapzen pokemongo openstreetmap layers offline mapsParis

-Next… well there is Road settings things I did today. If you check the road factory, you’ll see the settings property is quite extended now. It has an array of RoadSettings, where you can choose the road type (path, minor road, major road etc), road width and material.With this, it’ll be so much easier to change any settings in game. It’ll also easy to extend settings for more road types and options as well. I’ll try this for a while and if it works out well, I’ll do the same for other factories as well!

mapzen pokemongo openstreetmap layers offline maps road settings
-Then we have real building heights. I honestly thought I did this long ago but… well turns out I didn’t. It’s a small thing really, building factory now checks if the building has height property set, if it does uses that, if not takes a random number. That’s all.

-Also fixed some issues from Github page here. I’m also posting there on daily basis so please, don’t be shy to open new issues for bugs or feature requests. It’s much easier to discuss things there and I have 16 closed issues so… yeay!!!!

mapzen pokemongo openstreetmap layers offline maps buildings tokyoTokio

Yep, that’s all for this update I guess. Please do let me know what you think. I’m trying to build my road plan according to feedbacks, feature requests and bug reports.

Cheers,
Baran

Github Page
Download PokemonGO Clone Part 6: Offline Maps

mapzen pokemongo unity3d layers openstreetmap

PokemonGo clone using Mapzen – Part 5: Layers

Hey everyone, it has been a while but here I am with a huge update; single mesh layers, continuous roads, water&parks and more!

First of all, yea I know I shouldn’t be doing such huge updates and refactoring but I couldn’t help it this time. I got greedy and keep adding stuff. I’ll try to post smaller stuff more frequently from now on. I’m also sorry for the huge refactoring going on, it’s probably break everything if you built your stuff on previous versions but, trust me, totally worth it!

So what do we have here; (by here I mean; https://github.com/brnkhy/MapzenGo please do follow the github page as well, you can find latest fixes and stuff there.)

1) Single mesh layers is easily the biggest thing in this post. As you may remember, every single entity was a separate GameObject before which caused horrible performance and fps.  I was having issues even with 9 crowded tiles (see Paris) using that method.

What I did was simply merging meshes of same type entities under one single gameobject. For example, all buildings in a tile is single GameObject now. Or all roads, or parks. So instead thousands of small gameobject in every single tile, we have 4 now; Buildings, Roads, Water, Parks.

What’s the catch? Well you won’t be able to click&select buildings anymore. If you were planning anything like that, it might be better not to use layers (or handle click position and building relations differently in the background). And the tile creation is NOT threaded yet so it’ll stutter a little during the initial loading process. I’ll look into that as soon as possible as well.

Oh and you can activate/deactivate this thing from World Settings so you can still stick with the old system if you want!

mapzen pokemongo openstreetmap layersSee? This was pretty much impossible in previous versions but now you can enjoy the view in 70+ fps no problem (hopefully)

2) Continuous roads. Well not too continuous though. Let me explain; Mapzen road data is kinda hard to work with, it’s not a graph, not even properly connected. It’s just a bunch of, disconnected, unrelated road segments. So about continuous roads, yea it’s quite easy to make those road segments continuous, sure but almost impossible to create a connect all those segments, create a graph and smooth all together. OK, not impossible but not an easy task either so I’ll skip that for now.

mapzen pokemongo openstreetmap layers
As you can see, segments are continuous now but connections between segments still looks ugly. And yea it’s not smoothed either but it’ll be quite easy now that we have them in one piece.

3) Major refactoring. I really hate making big refactoring sessions like this but I really had to this time, mainly for layer things. Right now, building, water, road class are just keeping data. Removed all mesh generation code from those and moved them to factories. Admittedly it should have been like them from the beginning… my bad. But anyway, this new structure should be much better now. There is still some stuff to do there, but hopefully, won’t be this big.

4) Landuse layer! I almost forgot that but yea, we have a landuse/park layer now. Landuse layer has quite different stuff in there, bridges, parks, residential zones etc. I decided just to go with parks at the moment, as others made the general look messy. You can tweak it as you like, please let me know what about your work as well!

5) Also fixed some issues from Github Issues page. You can always post your reports/requests there as well. I’m actively using it!

mapzen pokemongo openstreetmap layers roads
Guess that’s it for now. Just run the sample and walk around Paris, you’ll see it’s soo much better than previous versions. I really hope you’ll like it as well.

Sooo what’s next? Not sure really, threading, visual improvements, more layers, custom objects, GPS, android build…. There is soo much to do and I’m quite sure I’m forgetting lots of other stuff. I’ll try to decide&post what’s next as soon as possible.

Please let me know what you think of this series, if you like it or not, if it’s useful for you, anything really.
Cheers,
Baran

Github Page
Download PokemonGO Clone Part 5: Layers

unity3d mapzen pokemongo water layer

PokemonGo clone using Mapzen – Part 4: Water Layer

Welcome back to the fourth part; Water layer, Git page, bug fixes and more!

-First of all, I finally created a git page for our little PokemonGo clone! You can find the latest fixes and updates, file bug reports, post feature requests there. I’ll be using it extensively so have no worries or hesitations about post there as well.

-Then we have some bug fixes. Previous versions didn’t really work properly in different detail levels for example. New tiles positions were messed up as well. They should be all fixed up now but yea, didn’t had time to test it extensively so please do let me know if you stumble upon anything weird. You can also read commit logs for more, I’m trying to write everything down properly there.

-There is also a parameter for tile sizes now. As you may remember, tile sizes wasn’t controlled in previous versions which caused countless problems. i.e. Lvl16 tiles were 611 unit wide while Lvl14 tiles were 2446 unit wide. Now we have a “TileSize” property under the world script, scaling down/up everything to fit tiles into that width&height.

-Last but not least, we now have a working water layer! It was a little tricky as there are lots of “MultiPolygons” in the water layer but turns out it isn’t that hard after all. I just did some silly mistakes which confused for a while. It happens. Occasionally. Sometimes frequently. But yea, with that fixed, we have a quite smooth water layer now. I just put a simple blue polygon for water but you can put Unity3D water over that easily.

unity3d mapzen pokemongo water layer
Yes, that’s Istanbul for you! Looking good? Nope? Yeah….

Hmmm am I missing something? Well it’s all on Git now, you can check all commits and commit messages for more. You can also check GitHub Issues page for known issues as well. I’m actively adding stuff there as well.

And that’s it. I guess. Please do let me know what you think about it or have any questions. Your feedback is what keeps me going. And page hits, share it will you? Thanks!

Cheers,
Baran

Download PokemonGO Clone Part 4: Water Layer

lots of tile osm mapzen unity3d pokemongo

PokemonGo clone using Mapzen – Part 3: Dynamic Tile Loader

As you may know, we already created a basic tile loader , player character and 3D buildings in the first two posts. Now we’ll try something a little more different, a dynamic tile loader. Admittedly I had no idea what to call it, “dynamic” might not be the best word here but couldn’t come up with anything better (and I’m open to suggestions). But it’s something that loads tiles dynamically…. well no. Whatever.

So what’s the problem we’re trying to solve here again? Well, Basic Loader gave us a central tile and n other tiles around it depending on the range parameter. But that’s a (quite small) finite set of tiles and you will eventually run off the map if you run in the same direction for a while.

We’ll take the most straight forward way to solve this; extend the world as player character gets close to any edge. There are lots and lots of different ways to really. I mean, how to detect player is getting close to an edge, how to load tiles or how many tiles to load etc. They’ll all have different properties and side effects but I think I’ve chosen one of the simplest ways and will try to explain it in detail now.

Wait actually before that, let’s have a look what we’re trying to achieve;

2016-08-02_00-36-44
Looking good? So let’s start!

  1. Yea guess I’ll try to enumerate like this. Anyway we’ll start with just like basic loader actually, one central tile and n tiles around it. Let’s say n=1 for the simplicity now, which yields 9 tiles, right? Something like this; (8 is the center tile, 2,3,4,7,9,12,13,14 are direct neighbors or Range1 tiles)tiles for dynamic tile loader mapzen osm pokemongo unity3d
  2. We’re safe as long as the player character stays inside tile 8. But as soon as it gets out of the central tile, we calculate a tile movement vector representing the players movement between tiles. i.e. for 8 -> 7, movement vector will be Vector2(-1,0). for 8 -> 4 it’ll be Vector2(1,-1). (see GetMovementVector method)
    One little problem here is; y-axis of the Unity3d coordinate system (or let’s say the scene I’m using) and TMS tile system is opposite. In other words, (0,0) is bottom-left in Unity3D while it’s top-left in TMS system. (see GetMovementVector method)
  3. We’ll pull a little trick here.. but let’s do it like this, what happens if the player character moves in a direction for hours? It’s a big big world as the songs says eh? Position vectors (of player, tiles and buildings) will grow and grow which will cause lots of precision problems after a while (7 digit numbers).
    So once player character leaves central tile, we’ll assign new tile as the central tile and move it back to (0,0) with everything around it. Doing this, everything will be kept around (0,0) all the time (see Centralize method) and with everything moved in one frame, you’ll nothing absolutely nothing at all on screen!
  4. So now we have everything in the (0,0) again. Now we can create new tiles using the very same function we used for basic loader. Remember we had 8 as central tile and loaded other around that? When the player moves to Tile 7, it becomes the new central tile and we’ll load neighboring tiles 1,6,11. Simple eh?
  5. One last thing, we don’t want to end up with hundreds of tiles on screen right? This is totally up to you actually but I’ll just assume that ,tiles further away more than d (from central tile in manhattan distance) are unnecessary, and simply destroy them (see UnloadTiles function).
    lots of tile osm mapzen unity3d pokemongo

I guess that’s all for now, had a lot more to talk about but it was a long day and I’m very very exhausted at the moment. I hope it’s still readable, I’m not even sure what I’m doing at this point.

I’ll try to post something like a todo list soon, consist of possible improvements on this. Will also post it on Github as soon as possible.
Hope you like this little dynamic tile loader thingy,  let me know what you think!

Cheers,
Baran

PS: just one more “dynamic tile loader” so that my SEO helper will shut up about low density -_-

 

v1.0:  Download PokemonGO Clone Part 3: Dynamic Tile Loader

Edit: There is a bug with the tile colliders at the moment. It collides with the player character, preventing him to move. I’ll fix and reupload it asap but untill then, you can simply move tile collider (big cube in (0,0,0)) to another tile and change “Layer Collision Settings” to prevent it colliding with anything. I did it like that but turns out “Layer Collision Settings” or even layers aren’t included into unitypackages. I’ll (hopefully) fix it in a few hours.

02.08.2016 – v1.1: Download PokemonGO Clone Part 3: Dynamic Tile Loader
-Fixed central tile collider problem by replacing it with a Rect

Unity_2016-07-27_22-42-19

PokemonGo clone using Mapzen – Part 2: 3D Buildings

In this second part, I added a player character and 3D buildings to our cute little PokemonGo clone!

It’ll be a short post really. I used the Ethan model from “Standard Assets” package. All I did was importing the package, simple as that. It works with WASD controls at the moment as that’s the easiest way to navigate during development process but I implement GPS coordinate based movement in the future as well.

3D buildings was even in the previous package actually. I somehow forgot it in there but the building heights was set to zero so it was quite hard to notice it. Anyway I fixed the bug and the code itself for better looking buildings. Just better, not beautiful… but we’ll get there, slowly. Generation code is quite straight forward but still I’ll try to explain shortly.

As you know from previous post; CreateMesh() function in the Building class takes the building corners as a List<Vector3> called verts. Those vectors (coming from Mapzen Api), or lets say the polygon generated from those vectors, gives us the base of the building. What I did was, to generate that polygon in the air and use it as a roof. Then for every edge in the roof, I created a side wall down to y=0 and viola!

PokemonGo - Player character and 3D Buildings

This yields quite simplistic, bare bone buildings as seen in PokemonGo. Should be enough for now but might give BuildR a chance in the future as well.

With character movement working, we have a new problem at hand; player can actually run to & fall off the map. We’ll fix that in the next post, by creating & loading new tiles dynamically as the player moves.

Hope you like it, Cheers,
Baran
Download PokemonGO Clone Part 2

mapzen

PokemonGo clone using Mapzen – Part 1: Basics

So my last post from 2014 December kinda exploded after the PokemonGo craziness and I decided to fix&improve it further. I’ll try to make a little blog post series on this one, starting with fixing/refactoring the old sample and then moving further and adding character movement, dynamic tile loader etc etc. I’m planning to have a proper Go clone when I’m done.

I’ll keep the post short as it’s quite time-consuming for me to write these as I’m still not feeling that comfortable writing in english (it’ll get there) but I’ll try to explain what’s going on as much as I can. But before we start, especially if you haven’t seen the old post, OpenStreetMap in Unity3D, I suggest checking that out first. It’ll be much easier/clear after that.

So first of all, you can get it here; PokemonGo clone – Mapzen sample and I’ll try to explain going over that here. Now extract the package, open scene file “BasicLoader” and run it.

PokemonGo clone

You should get something like this. Well it’s looks kinda ugly yea, but we’ll go into technical stuff before eye candy.

There are two gameobjects in the scene,
First one is the camera, which is pretty much standard camera with just one script (StrateCam) attached. It’s a quite handy little Orbit / RTS cam script.
Second one is “World” and that’s where all the magic happens.

Actually World script is just an entry / interface script. There is no logic or anything behind it, it’s just a container and starting point for the real thing; “TileManager”.

TileManager is the script responsible for handling everything about TMS tiles. For now, it just loads and created tiles but in the future posts, we’ll do a lot more here, like dynamically loading/destroy tiles depending on player position etc.

Tile script does pretty much everything (that sounds quite wrong, I know. Might refactor that later). It loads the data (this should be a service, bad idea doing it here), creates tile and uses BuildingFactory and RoadFactory classes to create building and road meshes/gameobjects respectively. As I said I’ll probably do some refactoring here but it’s quite straight forward for now. Load Data, create tile, load map image if necessary, create buildings create roads.

BuildingFactory and RoadFactory, are two simple factories for creating meshes and gameobjects given json objects and a relative position (owner tile center). We’ll add extra stuff like, fancy building model construction or curvy roads here. There are also some temporary (read wrong) stuff in there like using the first corner of a building/road as a unique identifier. Yes it’s wrong but somehow I couldn’t get Mapzen id’s to work for me couldn’t get my json parser to parse id’s properly , I’ll look into that later on as well.

And that’s pretty much it! Quite simple for now but I’ll be adding much more soon. Character movement and dynamic tile handling should be next two big things.

Hope you guys like it, let me know if you have any questions or whatever (I’ll be playing PokemonGo around),
Cheers, Baran

Download PokemonGO Clone using Mapzen Api Project

 

 

 

OpenStreetMap in Unity3D

Edit: New Post PokemonGO – Mapzen Post (26.07.2016)

This time I have something a little bit different; OpenStreetMap in Unity3D!

If you don’t know what OpenStreetMap is (well I didn’t until last week); it’s a crowd sourced map api created and supported by what seems to be a quite big community. So you can think of it as an open source (and free) Google/Bing Maps. And it gets even better, there are many other smaller projects/services built upon OpenStreetMap data, specializing in certain fields like metropol maps, metro maps etc. All these data under ODb License. How awesome is that?

So that is pretty much how I found about Mapzen and their Vector Tile Service, which by their own description “provides a free & open vector tile service for OpenStreetMap base layer data, with worldwide coverage updated daily, available in GeoJSON, TopoJSON, and binary data formats”.

I won’t go into detail about their service, format and everything but you can read all about it in their wiki page. What I’ll do though, is a walkthrough of parsing and visualizing their data in Unity3D so when we’re done, it’ll look something like this;

unity3d mapzen OpenStreetMap

On the left, you can see the original OpenStreetMap view and on the right, it’s the same data in triangles and debug lines… well yea I know I kinda suck at visualization.

Some bullets before we get started;

  • Note that I’ll just go over some important parts of the chode here, not the whole thing. You can find the project files at the bottom of the page anyway.
  • We’ll have to use three different coordinates systems and convert values back and forth to make this happen. First of all, we obviously have longitude & latitude, then we have OpenStreetMap tile coordinate system (origin at top left) and finally the 3D space coordinates in Unity3D, starting at bottom left (XZ plane). So you’ll see lots of conversion method calls and y axis sign chances through out the code. Becareful with those.
  • You can use this nice tool to find the tile you need; PHPCalc for OpenStreetMap . It’s a must-have tool if you’re planning to use OpenStreetMap in your project.

 

Also TMS (Tile Map Service) might be a little bit confusing at the begin but it’s actually just a grid system on a mercator projection. Only thing is, this grid has different detail levels. At level 1, it divides whole thing into 4 sections, at level 2, it’s 16 etc. Try these and you’ll get the idea; (0,0,1), (0,1,1), (1,0,1), (1,1,1). Those are x coordinate, y coordinate and detail level respectively. As you can see, just those 4 tiles covers up the whole world map in level one but that number increases really fast as the detail level increases.

For this post, I’ll use detail level 14 and 9685/6207 coordinates (yeap, my neighbourhood); so  (9685,6207,14).  But of course, that’s just an image of the data they provide, the real thing is actually here. That’s actually a readable link and goes like, “get me the building and road data for detail 14 at 9685×6207 coordinates”. I highly suggest using a JSON reformatter to be able to read it though (i.e. http://jsonviewer.stack.hu/).

So let’s get started;

public IEnumerator CreateTile(World w, Vector2 realPos, Vector2 worldCenter, int zoom)
{
    var tilename = realPos.x + "_" + realPos.y;
    var tileurl = realPos.x + "/" + realPos.y;
    var url = "http://vector.mapzen.com/osm/water,earth,buildings,roads,landuse/" + zoom + "/";

    JSONObject mapData;
    if (File.Exists(tilename))
    {
        var r = new StreamReader(tilename, Encoding.Default);
        mapData = new JSONObject(r.ReadToEnd());
    }
    else
    {
       var www = new WWW(url + tileurl + ".json");
       yield return www;

       var sr = File.CreateText(tilename);
       sr.Write(www.text);
       sr.Close();
       mapData = new JSONObject(www.text);
    }
    Rect = GM.TileBounds(realPos, zoom);
    CreateBuildings(mapData["buildings"]);
    CreateRoads(mapData["roads"]);
}

This is the entry point for whole process. Let’s have a look at it; it returns IEnumerator because I’m using WWW object and calling this function in a coroutine. Then we have 4 parameters; World is my main script to handle environment related stuff, not really necessary here. realPos is the x,y coordinates of the tile in TMS system (so 9685,6207). worldCenter is where we’ll create this tile in Unity3D space (it’s Vector2 as I’m using Y=0 by default). And zoom is the detail level.

Rest of it should be quite straight forward, I’m downloading and caching the JSON data. I believe there is already a WWW object with caching but I did it myself. This way it’ll be easier to chance database (text, xml, sql) whenever I want. So if we already have the data for that tile, it’ll re-use the old data file. If not, it’ll just download the data from the mapzen server.
I also used a third party library to parse JSON in C# (see JSONObject above). It’s nothing fancy really, just parses the data and creates something like a nested dictionary for it, which simplifies searching stuff.

And finally we have two big function calls; CreateBuildings and CreateRoads, taking related JSON sections, mapData[“buildings”] and mapData[“roads”], respectively. You can find those sections in the map Json and again, for your own sanity, use a JSON formatter.

Now let’s have a look at the CreateBuilding function;

private void CreateBuildings(JSONObject mapData)
{
	foreach (var geo in mapData["features"].list.Where(x => x["geometry"]["type"].str == "Polygon"))
	{
		var l = new List<Vector3>();
		for (int i = 0; i < geo["geometry"]["coordinates"][0].list.Count - 1; i++)
		{
			var c = geo["geometry"]["coordinates"][0].list[i];
			var bm = GM.LatLonToMeters(c[1].f, c[0].f);
			var pm = new Vector2(bm.x - Rect.center.x, bm.y - Rect.center.y);
			l.Add(pm.ToVector3xz());
		}

		try
		{
			var center = l.Aggregate((acc, cur) => acc + cur) / l.Count;
			if (!BuildingDictionary.ContainsKey(center))
			{
				var bh = new BuildingHolder(center, l);
				for (int i = 0; i < l.Count; i++)
				{
					l[i] = l[i] - bh.Center;
				}
				BuildingDictionary.Add(center, bh);

				var m = bh.CreateModel();
				m.name = "building";
				m.transform.parent = this.transform;
				m.transform.localPosition = center;
			}
		}
		catch (Exception ex)
		{
			Debug.Log(ex);
		}
	}
}

This is rather straight forward actually. I read vertex data for each building from the json object and create a mesh using those vertices using BuildingHolder class. Vertex coordinates are in lat/long system originally so first I convert them to meters (GM.LatLonToMeters call), then I substract the tile center from that as I attach buildings to tiles as children. I keep buildings inside a dictionary using their center point as key which isn’t a good idea and might cause problems with complex polygons (when a big concave polygon surround a smaller one, their centers may overlap). It’s good enough for now but you should consider finding a better key for them.

Another thing to note is that building vertices are kept relative to their center as well. So vertice positions are relative to the building center and building position is relative to the tile center, it’s a nice and clear hierarchical system. And building meshes are created inside that BuildingHolder class which makes it extremely easy to switch visuals. i.e. if you want 3D polygons, all you would need is to change whatever is inside that class to add height and the rest of the code will work just the same.

private void CreateRoads(JSONObject mapData)
{
	foreach (var geo in mapData["features"].list)
	{
		var l = new List<Vector3>();

		for (int i = 0; i < geo["geometry"]["coordinates"].list.Count; i++)
		{
			var c = geo["geometry"]["coordinates"][i];
			var bm = GM.LatLonToMeters(c[1].f, c[0].f);
			var pm = new Vector2(bm.x - Rect.center.x, bm.y - Rect.center.y);
			l.Add(pm.ToVector3xz());
		}

		var m = new GameObject("road").AddComponent<RoadPolygon>();
		m.transform.parent = this.transform;
		try
		{
			m.Initialize(geo["id"].str, this, l, geo["properties"]["kind"].str);
		}
		catch (Exception ex)
		{
			Debug.Log(ex);
		}
	}
}

CreateRoads is pretty much the same. Only different is taht I’m not generating polygons for the roads, just some debug lines so there is no mesh generation inside the RoadPolygon component. I’m just giving it the road vertices and it’ll draw lines between them in its update function.

You can find the project files below and there are a lot more than what’s covered here. Please do let me know if you have any questions or find any bugs/mistakes. I’m planning to write a few more blog posts on this, i.e. I already created a dynamic tiling system, which loads tiles as you move so you can travel all the way across usa or europe. Writing that was much easier than writing this blog post though, I’m having quite hard time writing in english so it may take some time 🙂

Anyway, let me know what you think!
Cheers!

UnityOsm.unitypackage (19.27 kb)

New Post PokemonGO – Mapzen Post
New Updated version (25/07/2016)

Random Planet Generator

So me and my collague found this brilliant blog post; Procedural Planet Generation by Andy Gainey a few days ago. Even though it looks beautiful and stuff, it’s written in javascript which isn’t a popular development platform here, so we decided to convert it to C# & Unity3D.

We’ve only done the icosahedron subdivision part for now, but still working on the rest actively.

 

 

You can find the Unity3D project files below but beware, it’s just a raw translation from Javascript to C# at the moment and looks quite ugly (I mean the coding style). I’ll do the refactoring and beautifying stuff when we’re done with it. That being said, we may not do a 100% conversion either and go on a different way at some point.

Anyway, I hope you guys find it useful, please do notify us about any bugs or issues in the C# version so we can fix it asap. Enjoy!

https://github.com/alprkskn/RandomPlanetGenerator