Skip to main content

Using web map services with three.js

In my previous three.js experiments (1, 2, 3, 4, 5) I've only used static files to load terrains and textures. Jarle Pedersen at the Norwegian Mapping Authority has been experimenting with web map services to create 3D terrains.

Jarle is using a modified Web Coverage Service (WCS) to transfer elevation data and a Web Map Service (WMS) for the texture. As WCS don't support a raster format easily parsed with JavaScript, he extended the service to deliver data in a gridded XYZ format (easting, northing and elevation). I've used this service to get elevation data for my map of Jotunheimen:

http://openwms.statkart.no/skwms1/wcs.dtm?SERVICE=WCS&VERSION=1.0.0&REQUEST=GetCoverage&COVERAGE=land_utm33_10m&FORMAT=XYZ&CRS=EPSG:32632&bbox=432000,6790000,492000,6850000&WIDTH=200&HEIGHT=200

The service returns data as text:

432150 6849850 1394.54736328125
432450 6849850 1448.778076171875
432750 6849850 1493.23046875
433050 6849850 1517.87548828125
...

The coordinates are in UTM 32 (meters). It's clearly not the most compact format. As long as we operate on a regular grid or triangle mesh we only need the altitude values. The altitude values could also be transferred in a binary format with less precision as shown in my previous blog post.

I've created a WCS terrain loader which sends the request and returns the altitude values from the response in a callback function.

var terrainLoader = new THREE.TerrainLoaderWCS();
terrainLoader.load(wcsUrl, function(data) {
  ...
});

Remember that you can only use this loader with a Web Coverage Service which returns data in the same XYZ format.

Getting texture data from a Web Map Service (WMS) works out of the box:

http://openwms.statkart.no/skwms1/wms.topo2?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&CRS=EPSG:32632&BBOX=432000,6790000,492000,6850000&WIDTH=2048&HEIGHT=2048&LAYERS=...&FORMAT=image/png

var material = new THREE.MeshPhongMaterial({
  map: THREE.ImageUtils.loadTexture(wmsUrl)
});

The map of Jotunheimen looks like this using these services (click to see in WebGL):



By using web maps services we can just change the geographic bounds and get map data for our area of interest:

http://turban.github.io/webgl-terrain/wxs/?epsg=32633&bbox=-11000,6675000,49000,6735000

Hardanger

http://turban.github.io/webgl-terrain/wxs/?epsg=32633&bbox=405000,7520000,465000,7580000

Lofoten Islands

For code simplicity I'm only operating on rectangular areas. See Jarle Pedersen's repository on GitHub if you want more choice.

See http://kartverket.no/Kart/Kartverksted/Lisens/ for the license terms and http://kartverket.no/Kart/Kartverksted/ for details on the web services.

Comments

Jarle Pedersen said…
Very nice to see people using the WCS. I've updated the post to include an english translation now.
Theo said…
Hi Bjorn

Very nice work, as always.

Please, however, always remember that there ways to transmit data that are much faster than using ASCII text files. Previously you have used binary beta. In my opinion, using heightmaps - which are ultimately are just compressed binary files - is a really fast, simple and easy way to go.

Here is Jotunheimen built using heightmaps. It's very much a work in progress. Nonetheless, heightmaps for all of Jonathan de Ferranti's HGT files are available. And the entire project - including the heightmaps is FOSS and on GitHub.

The next generation will get out of the 256 level PNG grey shade limit. And will access 1 second data where available.

The interesting thing is that this project is very much inspired and guided by your work - and your posts. You provide the simple techniques anybody can use. I am trying to follow in your footsteps - not just in Norway but over the entire globe.

In any case, I hope that you are enjoying your 'sabbatical' and are using the time to think of even better ways of designing 3D cartography.

The preview is showing issues with the link. So I copy it here:

http://jaanga.github.io/terrain-viewer/un-flatland/r10/un-flatland-r10.html#start=0#camalt=500#camlat=61.10639637138628#camlon=8.349609375#lat=61.63#lon=8.3#scale=4#tiles=10#tarlat=61.60639637138628#tarlon=8.349609375#zoom=11

And I have added Jotunheimen to the dropdown gazetteer if there still are issues.

Theo
Seany said…
Hi

I have a question. the modern three.js disables loading external sources as texture (cross origin policy) - however, you are accessing the WMS from an external browser. Which patch did you apply?
Bjørn Sandvik said…
Hi Seany,

I'm fetching data from an external WMS, so I guess they have enabled Cross-origin resource sharing (CORS).
x. lhomme said…
Hi

I've started a porject called GeoTiffParser.js :
https://github.com/xlhomme/GeotiffParser.js

My first attempt was to download a DEM from a WCS server (Geoserver) and obtaint elevation client side.

GeoTiffParser doesn't handled all GeoTiff format (compression Tiling),... there is still works to do. But I succeed to load my DEM via WCS.

xavier
Very nice post. I wonder if you can help me with javascrip and .hgt file to put into webpage.Thank you. Regards.
AKS said…
Hi Bjorn,

I read most of your blogs. It was quite informative and interesting. One thing I got stuck that while creating three D mesh using three.js I used texture from WMS. It all worked fine. But as I converted my WMS url to https, it stopped fetching texture from it. No errors in console. I am not able to understand what went wrong. I used a self signed certificate in WMS and my browser has already accepted this cerificate as trusted one.

Please suggest.

Popular posts from this blog

Creating a WebGL Earth with three.js

This blog post will show you how to create a WebGL Earth with three.js , a great JavaScript library which helps you to go 3D in the browser. I was surprised how easy it seemed when reading a blog post  by Jerome Etienne . So I decided to give it a try using earth textures  from one of my favourite cartographers, Tom Patterson . WebGL is a JavaScript API for rendering interactive 3D graphics in modern web browsers without the use of plug-ins. Three.js is built on top of WebGL, and allows you to create complex 3D scenes with a few lines of JavaScript. If your browser supports WebGL you should see a rotating Earth below: [ Fullscreen ] To be able to display something with three.js, you need three things: a scene, a camera and a renderer. var width  = window.innerWidth,     height = window.innerHeight; var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000); camera.position.z = 1.5; var rende...

Thematic Mapping Engine

It's time to introduce the Thematic Mapping Engine (TME). In my previous blog posts, I've shown various techniques of how geobrowsers can be used for thematic mapping. The goal has been to explore the possibilites and to make these techniques available to a wider audience. The Tematic Mapping Engine provides an easy-to-use web interface where you can create visually appealing maps on-the-fly. So far only prism maps are supported, but other thematic mapping techniques will be added in the upcoming weeks. The engine returns a KMZ file that you can open in Google Earth or download to your computer. My primary data source is UNdata . The above visualisation is generated by TME ( download KMZ ) and shows child mortaility in the world ( UNdata ). The Thematic Mapping Engine is also an example of what you can achieve with open source tools and datasets in the public domain: A world border dataset is loaded into a MySQL database . The same database contains tables with statistics ...

Creating 3D terrains with Cesium

Previously, I’ve used three.js to create 3D terrain maps in the browser ( 1 , 2 , 3 , 4 , 5 , 6 ). It worked great for smaller areas, but three.js doesn’t have built-in support for tiling and advanced LOD algorithms needed to render large terrains. So I decided to take Cesium for a spin. Cesium is a JavaScript library for creating 3D globes and 2D maps in the browser without a plugin. Like three.js, it uses WebGL for hardware-accelerated graphics. Cesium allows you to add your own terrain data, and this blog post will show you how. Impressed by the terrain rendering in @CesiumJS - with a 10m elevation model for Norway! Farewell Google Earth. pic.twitter.com/RQKvfu2hBb — Bjørn Sandvik (@thematicmapping) October 4, 2014 Compared to  the dying Google Earth plugin , it's quite complicated to get started with Cesium. The source code is well documented and the live coding Sandcastle is great, but there is a lack of tutorials  and my development slows down when ...