16 Jun 2021
Add Mapbox, Google Maps into Forge Viewer
Want to combine google-maps with your Revit model ? Then read on
INTRODUCTION
Use this Forge-Viewer extension to stream in Geo tiles from mapbox, bing maps, google maps, etc.
Under the hood, I ported the geo-three library, so you can use all of it's features (and multiple providers). Note that I did default to 'Planar' and 'RaycastingLOD' options, to minimize the library size.
DEMO: https://wallabyway.github.io/geo-three-ext/
SRC: https://github.com/wallabyway/geo-three-ext
WHAT ARE MAP-TILES ?
Imagine a photograph of the flat-Earth, chopped up into a square tiles. Now, divide those tiles into 4 tiles... and repeat.
These little tiles are called "Map Tiles", and can be arranged into an "image pyramid" based on their 'level of detail'. Each image is a small jpg file, and we assemble them into the three.js scene, based on the camera view.
Things closer to the camera, the higher the level of detail and more tiles loaded. Things far away from the camera - lower details. Like this debug image. Geo-three library handles this task, handles tile caching, does Earth Lat/Long calculations and connects to many "Map Tile providers" like Mapbox, Google-maps and Bing-maps.
GETTING STARTED
Add the "GeoThreeExtension" extension to viewer, like this:
viewer = new Autodesk.Viewing.Private.GuiViewer3D(div, { extensions: ["GeoThreeExtension"] });
and make sure to add the library, like this:
<script type="text/javascript" src="./geo-three.ext.js"></script>
CONFIGURATION
Set the center location of your model, by adjusting the map's position and tile starting point, like this:
map.position.set(14900,-27300,-45);
class MapPlaneNode extends MapNode {
constructor(parentNode = null, mapView = null, location = MapNode.ROOT, level = 7, x = 20, y = 49)
UPDATE:
Thanks to Duzmac for the stack overflow post that provides a great approach, to doing this (ie. figure out how to take your { lat / long / elevation } and convert them to { x,y,z and level } values, used above.
Note: To get Earth scale, you must set the level=0, and set..
UnitsUtils.EARTH_RADIUS = 6378137;
// move the camera into position:
var coords = Geo.UnitsUtils.datumsToSpherical(LAT, LONG);
cam.target.set(coords.x, 0, -coords.y);
cam.position.set(0, 1000, 0);
This will move the Forge-Viewer camera to the (LAT, LONG) position on Earth.
Note: You will also need to re-position the Forge Viewer's global-offset
Also, the camera navigation is not good at navigating a map. Consider adding THREE.MAPControl
Find me on Twitter: twitter.com/micbeale