Contour line data to DEM data - maps

I was just wondering if there was a way to use the free ordnance survey contour line data and generate DEM data using it. I’ve seen plenty of people converting DEM data to contour line data but not the other way around, could anyone help me out here?
I would also add more relevant tags to this question, though I do not have the reputation, nor do the tags exist

OS Terrain 50 is available as ASCII grid as well as contours. This OpenLayers example reads the unzipped ASCII files directly to produce a single zoom level EPSG:27700 tiled DEM (using the Mapbox RGB encoding method), but you could use similar logic in VB to create and save a PNG tile grid.
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/css/ol.css" type="text/css">
<style>
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.map {
width: 100%;
height: calc(100% - 20px);
}
</style>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.0/proj4.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<div>
<label>
Elevation
<span id="info">0.0</span> meters
</label>
</div>
<script type="text/javascript">
proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs ');
ol.proj.proj4.register(proj4);
var canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext('2d');
var imgData = ctx.createImageData(200, 200);
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
projection: 'EPSG:27700',
tileGrid: new ol.tilegrid.TileGrid({
tileSize: 200,
resolutions: [50],
extent: [0, 0, 700000, 1300000],
origin: [0, 0]
}),
crossOrigin: '',
imageSmoothing: false,
tileUrlFunction: function (tileCoord, pixelRatio, projection) {
var bounds = this.getTileGrid().getTileCoordExtent(tileCoord);
var x = (Math.round(bounds[0]/10)/10) + 10000;
var y = (Math.round(bounds[1]/10)/10) + 5000;
var a1y = (4 - (Math.floor(y/5000)%5))*5;
var a2y = (4 - (Math.floor(y/1000)%5))*5;
var y1 = Math.floor(y/100)%10;
a1y += (Math.floor(x/5000)%5);
a2y += (Math.floor(x/1000)%5);
var x1 = Math.floor(x/100)%10;
var tile500km = String.fromCharCode(a1y + Math.floor((a1y+17)/25) + "A".charCodeAt(0));
var tile100km = tile500km + String.fromCharCode(a2y + Math.floor((a2y+17)/25) + "A".charCodeAt(0));
var tile10km = tile100km + x1 + y1;
return 'https://mikenunn.net/data/terr50/grid/' + tile100km.toLowerCase() + '/' + tile10km + '.asc';
},
tileLoadFunction: function(tile, src) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('loadend', function (evt) {
var data = this.response;
if (data !== undefined) {
var rows = data.split('\n');
if (rows.length >= 205) {
for (var j = 0; j < 200; j++) {
var values = rows[j + 5].split(' ');
for (var i = 0; i < 200; i++) {
var pixel = (parseFloat(values[i]) * 10) + 100000;
var index = (j * 200 + i) * 4;
imgData.data[index] = (pixel >> 16) & 0xFF;
imgData.data[index+1] = (pixel >> 8) & 0xFF;
imgData.data[index+2] = (pixel >> 0) & 0xFF;
imgData.data[index+3] = 0xFF;
}
}
ctx.putImageData(imgData, 0, 0);
tile.getImage().src = canvas.toDataURL();
}
} else {
tile.setState(3);
}
});
xhr.addEventListener('error', function () {
tile.setState(3);
});
xhr.open('GET', src);
xhr.send();
}
})
});
var map = new ol.Map({
target: 'map',
layers: [layer],
view: new ol.View({
projection: 'EPSG:27700',
center: ol.proj.fromLonLat([0, 51.5], 'EPSG:27700'),
zoom: 14
})
});
var showElevations = function(evt) {
if (evt.dragging) {
return;
}
map.forEachLayerAtPixel(
evt.pixel,
function(layer, pixel) {
var height = -10000 + (pixel[0] * 256 * 256 + pixel[1] * 256 + pixel[2]) * 0.1;
info.innerHTML = height.toFixed(1);
},
{
layerFilter: function(candidate) {
return layer === candidate;
}
}
);
};
map.on('pointermove', showElevations);
</script>
</body>
</html>

Related

Raycaster display a Render

I use Threejs and I would like to create a function to display a descriptive card (Render() of Satllite.js) when I click on a Sphere. (Satellite.js)
/********** Imports **********/
import React, { PureComponent } from 'react';
import * as THREE from 'three';
import satData from '../data/sat.json';
export class Satellites extends PureComponent {
constructor(props) {
super(props)
this.state = { open: true }
this.x = {};
this.mouse = {};
this.raycaster = new THREE.Raycaster();
this.mouse = new THREE.Vector2();
}
onDocumentMouseDown = event => {
event.preventDefault()
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
// find intersections
this.raycaster.setFromCamera(this.mouse, this.props.camera)
this.intersects = this.raycaster.intersectObjects(
this.scene.className("card"),
false
)
if (this.intersects.length > 0) {
if (this.intersects[0].object.callback)
this.intersects[0].object.callback()
this.intersects[0].className(".card")
this.particle = new THREE.Sprite(this.particleMaterial)
this.particle.position.copy(this.intersects[0].point)
this.particle.scale.x = this.particle.scale.y = 16
this.props.scene.add(this.particle)
}
}
componentDidMount() {
// Satellite Sphere
// this.geometry = new THREE.SphereGeometry( this.props.data.r, 32, 32 );
this.geometry = new THREE.SphereGeometry(10, 32, 32)
this.material = new THREE.MeshBasicMaterial({ color: 0xffff00 })
this.sphere = new THREE.Mesh(this.geometry, this.material)
this.sphere.callback = function() {
console.log('Toto!')
}
this.sphere.position.set(50, 50, 50)
this.props.scene.add(this.sphere)
document.addEventListener('mousedown', this.onDocumentMouseDown, true)
}
// componentDidUpdate() {
// // update satelite pos.
// const radius = 10;
// const scale = radius * 1;
// this.sphere.scale.x = scale;
// this.sphere.scale.y = scale;
// this.sphere.scale.z = scale;
// }
componentWillUnmount() {
document.removeEventListener('mousedown', this.onDocumentMouseDown);
}
render() {
return (
<div>
{satData.map((satDetail, index) => {
return <div key={index} className="card">
<h2>{satDetail.satName.toUpperCase()}</h2>
<div className="cardImg" >
<img src={satDetail.satImg} alt={satDetail.satAlt} />
</div>
<div>
<p>Altitude : <span>{satDetail.alt}</span> km</p>
<p>Longitude : <span>{satDetail.long}</span> °</p>
<p>Latitude : <span>{satDetail.lat}</span> °</p>
</div>
<button onClick={this.closeModal}>Fermer</button>
</div>
})}
</div>
)
}
}
More details here
I got the code of a tutorial that show white squares but I would like to display my div ".card" which is in the "Render"
What is the method ?
Thanks for help !
This answer involves many topics combined, basically you need:
Raycast the mouse click and find the object intersection,
Get info by picked object,
Display it if object was selected, or hide if nothing was picked by mouse.
Test it here: http://jsfiddle.net/mmalex/9k4qbL8s/
let cardShown = false;
function showCard(userText) {
var divElement = $("#card");
if (divElement) {
if (!cardShown) {
divElement.css({
display: "block",
opacity: 0,
height: "0px"
});
}
divElement.text("Object color: " + userText);
if (!cardShown) {
setTimeout(function() {
divElement.css({
opacity: 1,
height: "16px"
});
}, 25);
}
cardShown = true;
}
}
function hideCard() {
var divElement = $("#card");
if (divElement) {
divElement.css({
height: "0px",
opacity: 0
});
cardShown = false;
}
}
var scene = new THREE.Scene();
var raycaster = new THREE.Raycaster();
//create some camera
camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 5;
camera.position.y = 5;
camera.position.z = 5;
camera.lookAt(0, 0, 0);
var controls = new THREE.OrbitControls(camera);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0x595959));
document.body.appendChild(renderer.domElement);
// white spotlight shining from the side, casting a shadow
var spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI / 6);
spotLight.position.set(4, 10, 7);
scene.add(spotLight);
// collect objects for raycasting,
// for better performance don't raytrace all scene
var clickableObjects = [];
var colors = new RayysWebColors();
for (let k = 0; k < 12; k++) {
var size = 0.5;
var geometry = new THREE.BoxGeometry(size, 0.2, size);
var randomColor = colors.pickRandom();
var material = new THREE.MeshPhongMaterial({
color: randomColor.hex,
transparent: true,
opacity: 0.75
});
var cube = new THREE.Mesh(geometry, material);
cube.userData.userText = randomColor.name;
cube.applyMatrix(new THREE.Matrix4().makeTranslation(k % 3, 0, Math.floor(k / 3) - 1));
scene.add(cube);
clickableObjects.push(cube);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
// this will be 2D coordinates of the current mouse position, [0,0] is middle of the screen.
var mouse = new THREE.Vector2();
var clickedObj; // this objects is hovered at the moment
// Following two functions will convert mouse coordinates
// from screen to three.js system (where [0,0] is in the middle of the screen)
function updateMouseCoords(event, coordsObj) {
coordsObj.x = ((event.clientX - renderer.domElement.offsetLeft + 0.5) / window.innerWidth) * 2 - 1;
coordsObj.y = -((event.clientY - renderer.domElement.offsetTop + 0.5) / window.innerHeight) * 2 + 1;
}
function onMouseUp(event) {
updateMouseCoords(event, mouse);
latestMouseProjection = undefined;
clickedObj = undefined;
raycaster.setFromCamera(mouse, camera); {
var intersects = raycaster.intersectObjects(clickableObjects);
if (intersects.length > 0) {
latestMouseProjection = intersects[0].point;
clickedObj = intersects[0].object;
showCard(clickedObj.userData.userText);
} else {
clickedObj = undefined;
hideCard();
}
}
}
window.addEventListener('mouseup', onMouseUp, false);
animate();

Load from JSON with dynamic patterns, patternSourceCanvas is not defined error return by the serialize JSON data

I am trying to save Fabric.js canvas and reload it using loadFromJson. But I am getting error patternSourceCanvas is not defined. I thought I should make it global so I removed var.
How to set the global variable in Fabric JS and use var patternSourceCanvas?
When I use the code below, then everything is working fine and the JSON is loaded easily.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.util.loadImage(t, function(t) {
var svg_width = i.width;
console.log('svg widh' + i.width + 'svg height' + i.height);
console.log('img width t'+ t.width + ' img height' + t.height);
if(svg_width >= 300){
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill({
source: t, repeat: 'repeat', offsetX:200 , offsetY : -110 // working
}), e.fabric.renderAll();
console.log('in if image 300 up ', t);
} else if (i.paths){
for (var r = 0; r < i.paths.length; r++)
i.paths[r].setPatternFill({
source: t, repeat: 'repeat' , offsetX: -100 , offsetY:-110
}), e.fabric.renderAll();
console.log('in image elseeee 300 up ', t);
}
}
})
But when I fill some other new shape with the new patternSourceCanvas variable then it's not working. Kindly help me with dynamic patterns.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.Image.fromURL(t, function (img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: function() {
patternSourceCanvas.setDimensions({
width: img.getScaledWidth() ,
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
return patternSourceCanvas.getElement();
},
repeat: r
});
console.log('pattern', pattern);
//p.set('fill', pattern);
canvas.renderAll();
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill(pattern);
} else if(i.paths) {
for (var r = 0; r < i.paths.length; r++) {
i.paths[r].setPatternFill(pattern);
}
}
e.fabric.renderAll();
});
You need to put patternSourceCanvas to global scope/ scope where loadFromJSON can access patternSourceCanvas. Else you can use cors enabled image directly.
DEMO
var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/22/Wikimapia_logotype.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
width: 200,
height: 200,
strokeWidth: 2,
stroke: '#000'
})
canvas.add(rect);
fabric.Image.fromURL(imageUrl, function(img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.setDimensions({
width: img.getScaledWidth(),
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: patternSourceCanvas.getElement()
},
function(patternObj) {
rect.fill = patternObj;
rect.dirty = true;
canvas.renderAll();
});
}, {
crossOrigin: 'annonymous'
});
function loadfromjson() {
var json = canvas.toJSON();
canvas.clear();
setTimeout(function() {
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
}, 1000)
}
canvas{
border:2px solid #000;
}
<canvas id="canvas" width="300" height="300"></canvas><br>
<button onclick="loadfromjson()">loadfromjson </button>
<script src='https://rawgit.com/kangax/fabric.js/master/dist/fabric.js'></script>

How to highlight cell in Anychart table when I click on that cell

Is there any way to highlight a cell in an Anychart table when I click on the cell?
I tried the following code, but it doesn't work.
table.listen("click",function(e){e.cellBorder(" #ff0000")});
Unfortunately, the current version of AnyChart 8.2.1 tables does not support events. But you can implement this functionality with some extra code. For details, please, check the sample below.
anychart.onDocumentReady(function () {
// set stage
var stage = anychart.graphics.create("container");
// create table
var table = anychart.standalones.table();
// set table content
table.contents([
[
null,
"2003 Sales",
"2004 Sales"
],[
"January",
"$10000",
"$12000"
],[
"February",
"$12000",
"$15000"
],[
"March",
"$18000",
"$16000"
],[
"April",
"$11000",
"$15000"
],
[
"May",
"$9000",
"$14000"
]
]);
var contents = table.contents();
// Set rows height.
table.rowsHeight(70);
table.getRow(0).fontWeight(900);
table.getCol(0).width(70).fontWeight(900); // Set first column width 70 px and bold the text
table.getCol(1).width(300);
table.getCol(2).width(300);
table.cellFill("#E1E1E1"); // Set table background color
// adjust table border and position text in each cell into center
table.cellBorder("#B8B8B8").vAlign("middle").hAlign("center");
// set table container and initiate draw
table.container(stage).draw();
var colsCount = table.colsCount();
var widths = [];
for(var i = 0; i<colsCount;i++) {
var width = table.getCol(i).width();
widths.push(width);
}
var rowHeight = table.rowsHeight();
// buffer cell
var buffer = 0;
var cont = document.getElementById('container');
cont.addEventListener('click', function(e) {
var x = e.clientX;
var y = e.clientY;
var indX = null;
var indY = null;
if(x < widths[0]) {
indX = 0;
}
if(x> widths[0] && x<widths[0] + widths[1]) {
indX = 1;
}
if(x > widths[0] + widths[1]) {
indX = 2;
}
indY = Math.floor(y / rowHeight);
// color selected cell
if (contents[indY]) {
table.getCell(indY,indX).fill("#0000ff", 0.2);
}
// color back
if (buffer !=0) {
buffer.fill("#e1e1e1")
}
// save selected cell to buffer
if (contents[indY]) {
buffer = table.getCell(indY,indX);
}
});
});
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<link href="https://cdn.anychart.com/releases/8.2.1/css/anychart-ui.min.css" rel="stylesheet"/>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-base.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-table.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-ui.min.js"></script>
<div id="container"></div>

Angular html 5 Audio mute in last Chrome and without spectrum

I have audio player directive, but in Chrome (and firefox) music mute in player and no draw spectrum. But in Opera and IE also its ok.
Help me find a Chrome (and firefox) bug...I think, i incorrect paste audio source in html.
var app = angular.module('app', []);
app.directive('spectrum', ['$document', '$timeout', function($document, $timeout) {
return function(scope, element, attr) {
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var audioVisual = document.getElementById('player');
//console.log(wrap);
// canvas stuff
var canvas = document.getElementById('c');
canvas_context = canvas.getContext('2d');
var gradient = canvas_context.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(1, '#550000');
gradient.addColorStop(0.75, '#ff0000');
gradient.addColorStop(0.25, '#ffff00');
gradient.addColorStop(0, '#ffff00');
canvas_context.fillStyle = gradient;
// audio stuff
audio = new Audio();
var audioSrc = 'http://www.noiseaddicts.com/samples/273.mp3';
//audio.__proto__ = scope.audio;
audio.src = audioSrc;
audio.controls = true;
audio.autoplay = true;
//scope.audios.paused = true;
audio.id = 'audioplayer';
audioVisual.appendChild(audio);
scope.audiosrc = audio.src;
// analyser stuff
var context = new AudioContext();
var analyser = context.createAnalyser();
analyser.fftSize = 2048;
// connect the stuff up to eachother/*
var source = context.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(context.destination);
freqAnalyser();
// draw the analyser to the canvas
function freqAnalyser() {
window.requestAnimFrame(freqAnalyser);
var sum;
var average;
var bar_width;
var scaled_average;
var num_bars = 60;
var data = new Uint8Array(128);
analyser.getByteFrequencyData(data);
// clear canvas
canvas_context.clearRect(0, 0, canvas.width, canvas.height);
var bin_size = Math.floor(data.length / num_bars);
for (var i = 0; i < num_bars; i += 1) {
sum = 0;
for (var j = 0; j < bin_size; j += 1) {
sum += data[(i * bin_size) + j];
}
average = sum / bin_size;
bar_width = canvas.width / num_bars;
scaled_average = (average / 256) * canvas.height;
canvas_context.fillRect(i * bar_width, canvas.height, bar_width - 2, - scaled_average);
}
}
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div spectrum>
<div class="spectrum">
<canvas id="c" width="500" height="200"></canvas>
</div>
<div id="player"><div id="audio-visual">
</div>
</div>
</div>

google maps v3 draw radius around a point

I am trying to create a map which allows a person to enter a zip code and a radius and will draw a radius around that point. The codeAddress function seems to work, but the drawCircle function is not working. Perhaps someone can pinpoint the error
see code below:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
#map_canvas { height: 100% }
</style>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false">
</script>
</script>
<script type= "text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
}
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function drawCircle() {
var radius=document.getElementById("radius").value;
geocoder.geocode( { 'address': address}, function(results, status){
if (status==google.maps.GeocoderStatus.OK){
var latlng=results[0].geometry.location;
var latitude=latlng.lat();
var longitude=latlng.lng();
}
else{
alert("Geocode was not successful for the following reason: " + status);
}
});
// Degrees to radians
var d2r = Math.PI / 180;
// Radians to degrees
var r2d = 180 / Math.PI;
// Earth radius is 3,963 miles
var cLat = (radius / 3963) * r2d;
var cLng = cLat / Math.cos(latitude * d2r);
//Store points in array
var points = [];
// Calculate the points
// Work around 360 points on circle
for (var i=0; i < 360; i++) {
var theta = Math.PI * (i/16);
// Calculate next X point
circleX = longitude + (cLng * Math.cos(theta));
// Calculate next Y point
circleY = latitude + (cLat * Math.sin(theta));
// Add point to array
points.push(new GPoint(circleX, circleY));
};
//Add points to map
var sColor=003F87;
var stroke=.5;
map.addOverlay(new GPolyline(points, sColor, stroke));
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:500px; height:460px;
-moz-outline-radius:20px; -moz-box-sizing:padding-box; -moz-outline-style:solid ;-moz-outline-color:#9FB6CD;
-moz-outline-width:10px;"></div>
<div>
Zip Code: <input id="address" type="textbox" value="">
Radius:<input id="radius" type="textbox" value="">
<input type="button" value="Find" onclick="codeAddress() ">
<input type="button" value="Draw Radius" onclick= "drawCircle() ">
</div>
</body>
</html>

Resources