Last active
March 8, 2017 10:15
-
-
Save i09158knct/9709636 to your computer and use it in GitHub Desktop.
2014-03-23 4th
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body{margin:0;padding:0;overflow:hidden} | |
.banner{background-color:rgba(204,204,204,0.333);position:fixed;top:0;left:0} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="container"></div> | |
<script src="http://jsrun.it/assets/h/r/V/O/hrVOk"></script><!-- d3.js --> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r66/three.min.js"></script><!-- three.js --> | |
<script src="http://jsrun.it/assets/x/8/7/3/x873l"></script><!-- TrackballControl.js --> | |
<div class="banner"> | |
<a href="http://portal.cyberjapan.jp/help/termsofuse.html">国土地理院</a> | |
<br> | |
© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.7.1 | |
// Source: https://gist.github.com/i09158knct/9709636#file-source-coffee | |
var camera, light1, light2, light3, renderer, scene; | |
window.lonlatToTile = function(lon, lat, zoom) { | |
var lonDegreesPerTile, numOfTiles, sinLat, tx, ty; | |
numOfTiles = Math.pow(2, zoom); | |
lonDegreesPerTile = 360 / numOfTiles; | |
sinLat = Math.sin(lat * Math.PI / 180); | |
tx = (lon + 180) / lonDegreesPerTile; | |
ty = (0.5 + -0.5 * Math.log((1 + sinLat) / (1 - sinLat)) / (2 * Math.PI)) * numOfTiles; | |
return [Math.floor(tx), Math.floor(ty)]; | |
}; | |
window.tileToLonlat = function(tx, ty, zoom) { | |
var lat, latRadians, lon, numOfTiles, x, y; | |
numOfTiles = Math.pow(2, zoom); | |
x = tx / numOfTiles; | |
y = ty / numOfTiles; | |
lon = (x - (1 / 2)) / (1 / 360); | |
latRadians = (y - (1 / 2)) / -(1 / (2 * Math.PI)); | |
lat = (2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2) / Math.PI * 180; | |
return [lon, lat]; | |
}; | |
window.tileToBoundary = function(x, y, zoom) { | |
var p1, p2; | |
p1 = tileToLonlat(x, y, zoom); | |
p2 = tileToLonlat(x + 1, y + 1, zoom); | |
return { | |
n: p1[1], | |
w: p1[0], | |
s: p2[1], | |
e: p2[0] | |
}; | |
}; | |
window.midpoint = function(_arg, _arg1) { | |
var x, x1, x2, y, y1, y2; | |
x1 = _arg[0], y1 = _arg[1]; | |
x2 = _arg1[0], y2 = _arg1[1]; | |
x = x1 - (x1 - x2) / 2; | |
y = y1 - (y1 - y2) / 2; | |
return [x, y]; | |
}; | |
window.centroid = function(boundary) { | |
var p1, p2; | |
p1 = [boundary.w, boundary.n]; | |
p2 = [boundary.e, boundary.s]; | |
return midpoint(p1, p2); | |
}; | |
window.createProjection = function(center) { | |
return d3.geo.mercator().scale(6.5 * 1000 * 1000).center(center).translate([0, 0]); | |
}; | |
window.loadDem = function(tile) { | |
var baseUrl, parseDemCsv, url; | |
parseDemCsv = function(text) { | |
return text.substring(0, text.length - 1).split('\n').map(function(row) { | |
return row.split(',').map(function(height) { | |
return parseFloat(height) || -1; | |
}); | |
}); | |
}; | |
baseUrl = 'http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt'; | |
url = baseUrl.replace(/\{([xyz])\}/g, function(match, key) { | |
return tile[key]; | |
}); | |
return $.get(url).then(parseDemCsv).done(function() { | |
return window.aaa = arguments; | |
}); | |
}; | |
window.loadTexture = function(tile) { | |
var baseUrl, url; | |
THREE.ImageUtils.crossOrigin = '*'; | |
baseUrl = 'http://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png'; | |
url = baseUrl.replace(/\{([xyz])\}/g, function(match, key) { | |
return tile[key]; | |
}); | |
return $.when(THREE.ImageUtils.loadTexture(url)); | |
}; | |
window.createGround = function(project, boundary, dem, mapimage) { | |
var geometry, ground, latDegreesPerSegment, lonDegreesPerSegment, xlength, ylength; | |
xlength = dem[0].length; | |
ylength = dem.length; | |
lonDegreesPerSegment = (boundary.e - boundary.w) / xlength; | |
latDegreesPerSegment = (boundary.n - boundary.s) / ylength; | |
geometry = new THREE.PlaneGeometry(0, 0, xlength - 1, ylength - 1); | |
dem.forEach(function(row, yindex) { | |
return row.forEach(function(height, xindex) { | |
var lat, lon, vertex, x, y, _ref; | |
lon = boundary.w + lonDegreesPerSegment * xindex; | |
lat = boundary.n - latDegreesPerSegment * yindex; | |
_ref = project([lon, lat]), x = _ref[0], y = _ref[1]; | |
vertex = geometry.vertices[xindex + (yindex * xlength)]; | |
vertex.x = x; | |
vertex.y = y; | |
return vertex.z = dem[yindex][xindex]; | |
}); | |
}); | |
ground = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ | |
map: mapimage, | |
opacity: 0.9, | |
transparent: true | |
})); | |
ground.rotation.x = 90 * Math.PI / 180; | |
ground.scale.z = -1; | |
return ground; | |
}; | |
window.loadOverpassData = function(boundary) { | |
var baseUrl, convertToAssoc, url; | |
convertToAssoc = function(rawData) { | |
var acc; | |
acc = { | |
node: {}, | |
way: {}, | |
relation: {} | |
}; | |
rawData.elements.forEach(function(elem) { | |
return acc[elem.type][elem.id] = elem; | |
}); | |
return acc; | |
}; | |
baseUrl = "http://overpass-api.de/api/interpreter?data=[out:json];\n(\n node({s},{w},{n},{e});\n way(bn);\n);\n(\n ._;\n node(w);\n);\nout;"; | |
url = baseUrl.replace(/\{([swne])\}/g, function(match, key) { | |
return boundary[key]; | |
}); | |
return $.getJSON(url).then(convertToAssoc); | |
}; | |
window.createGeoObject = function(project, overpassData) { | |
var createAndAddLines, createAndAddPolygons, createLine, createPolygon, findMaterialOptions, getNodes, isArea, lonlatToArray, materialOptions, nodeToVec3, nodeToXy, root, yxToVec3; | |
materialOptions = { | |
railway: { | |
platform: { | |
color: 0x555500, | |
amount: 10 | |
}, | |
rail: { | |
color: 0xffff00, | |
linewidth: 1 | |
} | |
}, | |
highway: { | |
pedestrian: { | |
color: 0x00cccc, | |
amount: 1 | |
}, | |
primary: { | |
color: 0xffaa555, | |
linewidth: 1000 | |
}, | |
secondary: { | |
color: 0xaa5500, | |
linewidth: 5 | |
}, | |
residential: { | |
color: 0xffffff, | |
linewidth: 2 | |
}, | |
"default": { | |
color: 0xcccccc, | |
linewidth: 1 | |
} | |
}, | |
waterway: { | |
"default": { | |
color: 0x0000ff, | |
linewidth: 10 | |
} | |
}, | |
amenity: { | |
school: { | |
color: 0x00aa00, | |
amount: 1000 | |
}, | |
theatre: { | |
color: 0xcc5500, | |
amount: 50 | |
}, | |
parking: { | |
color: 0xffffaa, | |
amount: 1 | |
}, | |
bus_station: { | |
color: 0xcc0000, | |
amount: 10 | |
}, | |
"default": { | |
color: 0xffffff, | |
amount: 100 | |
} | |
}, | |
building: { | |
commercial: { | |
color: 0x5555cc, | |
amount: 50 | |
}, | |
yes: { | |
color: 0x888888, | |
amount: 25, | |
vertexColors: THREE.VertexColors | |
}, | |
"default": { | |
color: 0xffffff, | |
amount: 1 | |
} | |
}, | |
natural: { | |
wood: { | |
color: 0x00ff00, | |
amount: 50 | |
}, | |
water: { | |
color: 0x0000cc, | |
amount: 5 | |
}, | |
"default": { | |
color: 0x00ff00, | |
amount: 1000 | |
} | |
}, | |
leisure: { | |
pitch: { | |
color: 0xcc5500, | |
amount: 5 | |
}, | |
golf_course: { | |
color: 0x00cc55, | |
amount: 5 | |
}, | |
"default": { | |
color: 0x00cc55, | |
amount: 1000 | |
} | |
}, | |
landuse: { | |
forest: { | |
color: 0x00ff00, | |
amount: 100 | |
}, | |
old_forest: { | |
color: 0x005500, | |
amount: 100 | |
}, | |
"default": { | |
color: 0x005500, | |
amount: 500 | |
} | |
} | |
}; | |
getNodes = function(overpassData, way) { | |
return way.nodes.map(function(id) { | |
return overpassData.node[id]; | |
}); | |
}; | |
isArea = function(way) { | |
var first, last; | |
first = way.nodes[0]; | |
last = way.nodes[way.nodes.length - 1]; | |
return first === last; | |
}; | |
lonlatToArray = function(_arg) { | |
var lat, lon; | |
lon = _arg.lon, lat = _arg.lat; | |
return [lon, lat]; | |
}; | |
yxToVec3 = function(_arg) { | |
var x, y; | |
x = _arg[0], y = _arg[1]; | |
return new THREE.Vector3(x, y, 0); | |
}; | |
nodeToXy = function(node) { | |
return project(lonlatToArray(node)); | |
}; | |
nodeToVec3 = function(node) { | |
return yxToVec3(nodeToXy(node)); | |
}; | |
createLine = function(way, opts) { | |
var create, line; | |
create = (function(_this) { | |
return function(way) { | |
var geometry, nodes; | |
nodes = getNodes(overpassData, way); | |
geometry = new THREE.Geometry(); | |
geometry.vertices = nodes.map(function(node) { | |
return nodeToVec3(node); | |
}); | |
return geometry; | |
}; | |
})(this); | |
return line = new THREE.Line(create(way), new THREE.LineBasicMaterial(opts)); | |
}; | |
createPolygon = function(area, opts) { | |
var create, createShape, polygon; | |
if (opts == null) { | |
opts = { | |
color: 0xffffff, | |
opacity: 0.8, | |
transparent: true | |
}; | |
} | |
createShape = function(nodes) { | |
var shape; | |
shape = new THREE.Shape(); | |
shape.moveTo.apply(shape, nodeToXy(nodes[0])); | |
nodes.slice(1).forEach((function(_this) { | |
return function(node) { | |
return shape.lineTo.apply(shape, nodeToXy(node)); | |
}; | |
})(this)); | |
return shape; | |
}; | |
create = (function(_this) { | |
return function(area, opts) { | |
var geometry, nodes, shape; | |
nodes = getNodes(overpassData, area); | |
shape = createShape(nodes); | |
geometry = shape.extrude(_.defaults(opts, { | |
amount: 5, | |
bevelEnabled: false | |
})); | |
geometry.computeFaceNormals(); | |
return geometry; | |
}; | |
})(this); | |
return polygon = new THREE.Mesh(create(area, opts), new THREE.MeshLambertMaterial(_.defaults(opts, { | |
side: THREE.BackSide | |
}))); | |
}; | |
findMaterialOptions = function(tags) { | |
var category, key, mkeys, tkeys, tvalue, _ref; | |
if (tags == null) { | |
tags = {}; | |
} | |
mkeys = _.keys(materialOptions); | |
tkeys = _.keys(tags); | |
key = _.first(_.intersection(mkeys, tkeys)); | |
if (key != null) { | |
category = materialOptions[key]; | |
tvalue = tags[key]; | |
return (_ref = category[tvalue]) != null ? _ref : category["default"]; | |
} else { | |
return null; | |
} | |
}; | |
createAndAddLines = function(root) { | |
var ways; | |
ways = _.filter(overpassData.way, function(way) { | |
return !isArea(way); | |
}); | |
return _.each(ways, function(way) { | |
var opts; | |
opts = findMaterialOptions(way.tags); | |
return root.add(createLine(way, opts)); | |
}); | |
}; | |
createAndAddPolygons = function(root) { | |
var areas; | |
areas = _.filter(overpassData.way, isArea); | |
return _.each(areas, function(area) { | |
var opts; | |
opts = findMaterialOptions(area.tags); | |
return root.add(createPolygon(area, opts)); | |
}); | |
}; | |
root = new THREE.Object3D(); | |
root.rotation.x = 90 * Math.PI / 180; | |
root.scale.z = -1; | |
createAndAddLines(root); | |
createAndAddPolygons(root); | |
return root; | |
}; | |
window.tileKaruizawa = { | |
x: 14501, | |
y: 6414, | |
z: 14 | |
}; | |
scene = window.scene = null; | |
renderer = window.renderer = null; | |
light1 = window.light1 = null; | |
light2 = window.light2 = null; | |
light3 = window.light3 = null; | |
camera = window.camera = null; | |
$(function() { | |
var atmospere, boundary, center, loading, project, targetTile; | |
scene = new THREE.Scene(); | |
renderer = new THREE.WebGLRenderer(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
document.getElementById('container').appendChild(renderer.domElement); | |
light1 = new THREE.DirectionalLight(0xffffffff, 1); | |
light2 = new THREE.DirectionalLight(0xffffffff, 0.3); | |
light3 = new THREE.DirectionalLight(0xffffffff, 1); | |
light1.position.set(1000, -10000, 750); | |
light2.position.set(-1000, -1000, -750); | |
light3.position.set(1000, 1000, 750); | |
scene.add(light1); | |
scene.add(light2); | |
scene.add(light3); | |
atmospere = new THREE.Mesh(new THREE.SphereGeometry(20000, 60, 49), new THREE.MeshBasicMaterial({ | |
color: 0xeeeeff | |
})); | |
atmospere.scale.x = -1; | |
scene.add(atmospere); | |
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 40 * 1000); | |
camera.position.set(-3000, 3000, -3000); | |
scene.add(camera); | |
targetTile = window.tileKaruizawa; | |
boundary = tileToBoundary(targetTile.x, targetTile.y, targetTile.z); | |
center = centroid(boundary); | |
project = createProjection(center); | |
loading = $.when.apply($, [loadDem(targetTile), loadTexture(targetTile), loadOverpassData(boundary)]); | |
return loading.then(function(dem, mapimage, overpassData) { | |
var animate, controls, geoObject; | |
window.ground = createGround(project, boundary, dem, mapimage); | |
ground.position.y = -950; | |
scene.add(ground); | |
geoObject = createGeoObject(project, overpassData); | |
scene.add(geoObject); | |
controls = new THREE.TrackballControls(camera, renderer.domElement); | |
controls.target = new THREE.Vector3(0, 0, 0); | |
return requestAnimationFrame(animate = function() { | |
requestAnimationFrame(animate); | |
controls.update(); | |
return renderer.render(scene, camera); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://developers.google.com/maps/documentation/javascript/examples/map-coordinates | |
window.lonlatToTile = (lon, lat, zoom) -> | |
numOfTiles = 2 ** zoom | |
lonDegreesPerTile = 360 / numOfTiles | |
sinLat = Math.sin(lat * Math.PI / 180) | |
tx = (lon + 180) / lonDegreesPerTile | |
ty = (0.5 + -0.5 * Math.log((1 + sinLat) / (1 - sinLat)) / (2 * Math.PI)) * numOfTiles | |
[Math.floor(tx), Math.floor(ty)] | |
window.tileToLonlat = (tx, ty, zoom) -> | |
numOfTiles = 2 ** zoom | |
x = tx / numOfTiles | |
y = ty / numOfTiles | |
lon = (x - (1 / 2)) / (1 / 360) | |
latRadians = (y - (1 / 2)) / -(1 / (2 * Math.PI)) | |
lat = (2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2) / Math.PI * 180 | |
[lon, lat] | |
window.tileToBoundary = (x, y, zoom) -> | |
p1 = tileToLonlat(x, y, zoom) | |
p2 = tileToLonlat(x + 1, y + 1, zoom) | |
n: p1[1] | |
w: p1[0] | |
s: p2[1] | |
e: p2[0] | |
window.midpoint = ([x1, y1], [x2, y2]) -> | |
x = x1 - (x1 - x2) / 2 | |
y = y1 - (y1 - y2) / 2 | |
[x, y] | |
window.centroid = (boundary) -> | |
p1 = [boundary.w, boundary.n] | |
p2 = [boundary.e, boundary.s] | |
midpoint(p1, p2) | |
window.createProjection = (center) -> | |
d3.geo.mercator() | |
.scale(6.5 * 1000 * 1000) | |
.center(center) | |
.translate([0, 0]) | |
window.loadDem = (tile) -> | |
parseDemCsv = (text) -> | |
text.substring(0, text.length - 1) | |
.split('\n') | |
.map (row) -> | |
row.split(',').map (height) -> | |
parseFloat(height) || -1 | |
baseUrl = 'http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt' | |
url = baseUrl.replace /\{([xyz])\}/g, (match, key) -> tile[key] | |
$.get(url) | |
.then(parseDemCsv) | |
.done -> window.aaa = arguments | |
window.loadTexture = (tile) -> | |
THREE.ImageUtils.crossOrigin = '*' | |
baseUrl = 'http://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png' | |
url = baseUrl.replace /\{([xyz])\}/g, (match, key) -> tile[key] | |
$.when(THREE.ImageUtils.loadTexture(url)) | |
window.createGround = (project, boundary, dem, mapimage) -> | |
xlength = dem[0].length | |
ylength = dem.length | |
lonDegreesPerSegment = (boundary.e - boundary.w) / xlength | |
latDegreesPerSegment = (boundary.n - boundary.s) / ylength | |
geometry = new THREE.PlaneGeometry \ | |
0, 0, # initial geometry size | |
xlength - 1, ylength - 1 # segments | |
dem.forEach (row, yindex) -> | |
row.forEach (height, xindex) -> | |
lon = boundary.w + lonDegreesPerSegment * xindex | |
lat = boundary.n - latDegreesPerSegment * yindex | |
[x, y] = project [lon, lat] | |
vertex = geometry.vertices[xindex + (yindex * xlength)] | |
vertex.x = x | |
vertex.y = y | |
vertex.z = dem[yindex][xindex] | |
ground = new THREE.Mesh \ | |
geometry, | |
new THREE.MeshBasicMaterial | |
map: mapimage | |
opacity: 0.9 | |
transparent: true | |
# side: THREE.DoubleSide | |
ground.rotation.x = 90 * Math.PI / 180 | |
ground.scale.z = -1 | |
ground | |
window.loadOverpassData = (boundary) -> | |
convertToAssoc = (rawData) -> | |
acc = | |
node: {} | |
way: {} | |
relation: {} | |
rawData.elements.forEach (elem) -> | |
acc[elem.type][elem.id] = elem | |
acc | |
baseUrl = | |
""" | |
http://overpass-api.de/api/interpreter?data=\ | |
[out:json]; | |
( | |
node({s},{w},{n},{e}); | |
way(bn); | |
); | |
( | |
._; | |
node(w); | |
); | |
out; | |
""" | |
url = baseUrl.replace /\{([swne])\}/g, (match, key) -> boundary[key] | |
$.getJSON(url) | |
.then(convertToAssoc) | |
window.createGeoObject = (project, overpassData) -> | |
materialOptions = | |
railway: | |
platform: | |
color: 0x555500 | |
amount: 10 | |
rail: | |
color: 0xffff00 | |
linewidth: 1 | |
highway: | |
pedestrian: | |
color: 0x00cccc | |
amount: 1 | |
primary: | |
color: 0xffaa555 | |
linewidth: 1000 | |
# fog: true | |
secondary: | |
color: 0xaa5500 | |
linewidth: 5 | |
# fog: true | |
residential: | |
color: 0xffffff | |
linewidth: 2 | |
# fog: true | |
default: | |
color: 0xcccccc | |
linewidth: 1 | |
# fog: true | |
waterway: | |
default: | |
color: 0x0000ff | |
linewidth: 10 | |
# fog: true | |
amenity: | |
school: | |
color: 0x00aa00 | |
amount: 1000 | |
theatre: | |
color: 0xcc5500 | |
amount: 50 | |
parking: | |
color: 0xffffaa | |
amount: 1 | |
bus_station: | |
color: 0xcc0000 | |
amount: 10 | |
default: | |
color: 0xffffff | |
amount: 100 | |
building: | |
commercial: | |
color: 0x5555cc | |
amount: 50 | |
yes: | |
color: 0x888888 | |
amount: 25 | |
vertexColors: THREE.VertexColors | |
default: | |
color: 0xffffff | |
amount: 1 | |
natural: | |
wood: | |
color: 0x00ff00 | |
amount: 50 | |
water: | |
color: 0x0000cc | |
amount: 5 | |
default: | |
color: 0x00ff00 | |
amount: 1000 | |
leisure: | |
pitch: | |
color: 0xcc5500 | |
amount: 5 | |
golf_course: | |
color: 0x00cc55 | |
amount: 5 | |
default: | |
color: 0x00cc55 | |
amount: 1000 | |
landuse: | |
forest: | |
color: 0x00ff00 | |
amount: 100 | |
old_forest: | |
color: 0x005500 | |
amount: 100 | |
default: | |
color: 0x005500 | |
amount: 500 | |
getNodes = (overpassData, way) -> | |
way.nodes.map (id) -> | |
overpassData.node[id] | |
isArea = (way) -> | |
first = way.nodes[0] | |
last = way.nodes[way.nodes.length - 1] | |
first == last | |
lonlatToArray = ({lon, lat}) -> [lon, lat] | |
yxToVec3 = ([x, y]) -> new THREE.Vector3(x, y, 0) | |
nodeToXy = (node) -> project(lonlatToArray(node)) | |
nodeToVec3 = (node) -> yxToVec3(nodeToXy(node)) | |
createLine = (way, opts) -> | |
create = (way) => | |
nodes = getNodes(overpassData, way) | |
geometry = new THREE.Geometry() | |
geometry.vertices = nodes.map (node) -> | |
nodeToVec3(node) | |
geometry | |
line = new THREE.Line \ | |
create(way), | |
new THREE.LineBasicMaterial opts | |
createPolygon = (area, opts={color: 0xffffff, opacity: 0.8, transparent: true}) -> | |
createShape = (nodes) -> | |
shape = new THREE.Shape() | |
shape.moveTo(nodeToXy(nodes[0])...) | |
nodes.slice(1).forEach (node) => | |
shape.lineTo(nodeToXy(node)...) | |
shape | |
create = (area, opts) => | |
nodes = getNodes(overpassData, area) | |
shape = createShape(nodes) | |
geometry = shape.extrude _.defaults opts, | |
amount: 5 | |
bevelEnabled: false | |
geometry.computeFaceNormals() | |
geometry | |
polygon = new THREE.Mesh \ | |
create(area, opts), | |
new THREE.MeshLambertMaterial _.defaults opts, | |
side: THREE.BackSide | |
findMaterialOptions = (tags={}) -> | |
mkeys = _.keys(materialOptions) | |
tkeys = _.keys(tags) | |
key = _.first(_.intersection(mkeys, tkeys)) | |
if key? | |
category = materialOptions[key] | |
tvalue = tags[key] | |
category[tvalue] ? category.default | |
else | |
null | |
createAndAddLines = (root) -> | |
ways = _.filter overpassData.way, (way) -> !isArea(way) | |
_.each ways, (way) -> | |
opts = findMaterialOptions(way.tags) | |
root.add(createLine(way, opts)) | |
createAndAddPolygons = (root) -> | |
areas = _.filter overpassData.way, isArea | |
_.each areas, (area) -> | |
opts = findMaterialOptions(area.tags) | |
root.add(createPolygon(area, opts)) | |
root = new THREE.Object3D() | |
root.rotation.x = 90 * Math.PI / 180 | |
root.scale.z = -1 | |
createAndAddLines(root) | |
createAndAddPolygons(root) | |
root | |
window.tileKaruizawa = | |
x: 14501 | |
y: 6414 | |
z: 14 | |
scene = window.scene = null | |
renderer = window.renderer = null | |
light1 = window.light1 = null | |
light2 = window.light2 = null | |
light3 = window.light3 = null | |
camera = window.camera = null | |
$ -> | |
scene = new THREE.Scene() | |
renderer = new THREE.WebGLRenderer() | |
renderer.setSize(window.innerWidth, window.innerHeight) | |
document.getElementById('container').appendChild(renderer.domElement) | |
light1 = new THREE.DirectionalLight(0xffffffff, 1) | |
light2 = new THREE.DirectionalLight(0xffffffff, 0.3) | |
light3 = new THREE.DirectionalLight(0xffffffff, 1) | |
light1.position.set(1000, -10000, 750) | |
light2.position.set(-1000, -1000, -750) | |
light3.position.set(1000, 1000, 750) | |
scene.add(light1) | |
scene.add(light2) | |
scene.add(light3) | |
atmospere = new THREE.Mesh \ | |
new THREE.SphereGeometry(20000, 60, 49), | |
new THREE.MeshBasicMaterial(color: 0xeeeeff) | |
atmospere.scale.x = -1 | |
scene.add atmospere | |
camera = new THREE.PerspectiveCamera \ | |
70, | |
window.innerWidth / window.innerHeight, | |
1, | |
40 * 1000 | |
camera.position.set(-3000, 3000, -3000) | |
scene.add(camera) | |
targetTile = window.tileKaruizawa | |
boundary = tileToBoundary(targetTile.x, targetTile.y, targetTile.z) | |
center = centroid(boundary) | |
project = createProjection(center) | |
loading = $.when [ | |
loadDem(targetTile) | |
loadTexture(targetTile) | |
loadOverpassData(boundary) | |
]... | |
loading.then (dem, mapimage, overpassData) -> | |
window.ground = createGround(project, boundary, dem, mapimage) | |
ground.position.y = -950 | |
scene.add(ground) | |
geoObject = createGeoObject(project, overpassData) | |
scene.add(geoObject) | |
controls = new THREE.TrackballControls(camera, renderer.domElement) | |
controls.target = new THREE.Vector3(0, 0, 0) | |
requestAnimationFrame animate = -> | |
requestAnimationFrame(animate) | |
controls.update() | |
renderer.render(scene, camera) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment