Sunday, 16 March 2014

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.

7 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

Cătălin George Feștilă said...

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.