kopia lustrzana https://github.com/robhawkes/vizicities
Added basic building functionality
rodzic
1c5fe32f72
commit
a723a4c0dd
|
@ -22,9 +22,11 @@ module.exports = function(grunt) {
|
|||
'src/shared/vendor/q.js',
|
||||
'src/shared/vendor/three/three.js',
|
||||
'src/shared/vendor/three/ColorConverter.js',
|
||||
'src/shared/vendor/d3.js',
|
||||
'src/client/Vizi.js',
|
||||
'src/client/Log.js',
|
||||
'src/client/Mediator.js',
|
||||
'src/client/Geo.js',
|
||||
'src/client/City.js',
|
||||
'src/client/Loop.js',
|
||||
'src/client/webgl/WebGL.js',
|
||||
|
@ -34,7 +36,8 @@ module.exports = function(grunt) {
|
|||
'src/client/objects/ObjectManager.js',
|
||||
'src/client/objects/BuildingManager.js',
|
||||
'src/client/objects/Object.js',
|
||||
'src/client/objects/Floor.js'
|
||||
'src/client/objects/Floor.js',
|
||||
'src/client/objects/Building.js'
|
||||
],
|
||||
dest: 'build/vizi.js'
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
<script>
|
||||
var city = new VIZI.City();
|
||||
city.loadBuildings("osm-buildings.json");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,14 @@
|
|||
VIZI.Log("Inititialising city");
|
||||
|
||||
_.extend(this, VIZI.Mediator);
|
||||
|
||||
// Set up geo methods
|
||||
this.geo = VIZI.Geo.getInstance({
|
||||
areaCoords: {
|
||||
bottomLeft: [-0.090062,51.489438],
|
||||
topRight: [0.012322,51.519747]
|
||||
}
|
||||
});
|
||||
|
||||
// Set up basic WebGL components (scene, camera, lights, renderer)
|
||||
this.webgl = new VIZI.WebGL();
|
||||
|
@ -24,6 +32,11 @@
|
|||
VIZI.Log("Loading buildings");
|
||||
|
||||
var buildingManager = new VIZI.BuildingManager();
|
||||
buildingManager.load(url).then(console.log, console.error).done();
|
||||
buildingManager.load(url).then(function(value) {
|
||||
VIZI.Log(value);
|
||||
buildingManager.process(value);
|
||||
}, function(error) {
|
||||
console.error(error.stack);
|
||||
}).done();
|
||||
};
|
||||
}());
|
|
@ -0,0 +1,47 @@
|
|||
/* globals window, _, VIZI, d3 */
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
VIZI.Geo = (function() {
|
||||
var Geo = function(options) {
|
||||
this.projection = this.setProjection(options.areaCoords);
|
||||
this.pixelsPerMeter = this.setPixelsPerMeter();
|
||||
};
|
||||
|
||||
Geo.prototype.setProjection = function(areaCoords) {
|
||||
return d3.geo.mercator()
|
||||
.center([
|
||||
areaCoords.bottomLeft[0] + (areaCoords.topRight[0] - areaCoords.bottomLeft[0]) / 2,
|
||||
areaCoords.bottomLeft[1] + (areaCoords.topRight[1] - areaCoords.bottomLeft[1]) / 2
|
||||
]) // Geographic coordinates of map centre
|
||||
.translate([0, 0]) // Pixel coordinates of .center()
|
||||
.scale(10000000);
|
||||
};
|
||||
|
||||
// TODO: Stop using London as a base for this
|
||||
Geo.prototype.setPixelsPerMeter = function() {
|
||||
var metersPerLat = 111200;
|
||||
var pixelsPerLat = this.projection([0, 50])[1] - this.projection([0, 51])[1];
|
||||
return pixelsPerLat / metersPerLat;
|
||||
};
|
||||
|
||||
var instance;
|
||||
|
||||
// an emulation of static variables and methods
|
||||
var _static = {
|
||||
name: "VIZI.Geo",
|
||||
|
||||
// Method for getting an instance. It returns
|
||||
// a singleton instance of a singleton object
|
||||
getInstance: function( options ) {
|
||||
if ( instance === undefined ) {
|
||||
instance = new Geo( options );
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
return _static;
|
||||
}());
|
||||
}());
|
|
@ -6,7 +6,7 @@
|
|||
VERSION: 1.0
|
||||
};
|
||||
|
||||
// List any constants here, like:
|
||||
// List any constants or helper functions here, like:
|
||||
// https://github.com/mrdoob/three.js/blob/master/src/Three.js
|
||||
|
||||
// Expose VIZI to the window
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* globals window, _, VIZI, THREE */
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
VIZI.Building = function(feature) {
|
||||
VIZI.Log("Inititialising building object");
|
||||
|
||||
VIZI.Object.call(this);
|
||||
|
||||
this.materials = [
|
||||
new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors})
|
||||
];
|
||||
|
||||
this.object = this.createObject(feature);
|
||||
};
|
||||
|
||||
VIZI.Building.prototype = Object.create( VIZI.Object.prototype );
|
||||
|
||||
// TODO: Handle multi-polygons
|
||||
VIZI.Building.prototype.createObject = function(feature) {
|
||||
var properties = feature.properties;
|
||||
|
||||
var area = properties.area;
|
||||
|
||||
// Skip if building area is too small
|
||||
if (area < 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
var colour = new THREE.Color(0xcccccc);
|
||||
|
||||
var coords = feature.geometry.coordinates[0];
|
||||
var shape = this.createShapeFromCoords(coords);
|
||||
|
||||
var height = 10 * this.geo.pixelsPerMeter;
|
||||
|
||||
var extrudeSettings = { amount: height, bevelEnabled: false };
|
||||
var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
|
||||
|
||||
VIZI.applyVertexColors( geom, colour );
|
||||
|
||||
// Move geom to 0,0 and return offset
|
||||
// var offset = THREE.GeometryUtils.center( geom );
|
||||
|
||||
geom.computeFaceNormals();
|
||||
var mesh = new THREE.Mesh(geom, this.materials[0]);
|
||||
|
||||
mesh.position.y = height;
|
||||
|
||||
// Flip buildings as they are up-side down
|
||||
mesh.rotation.x = 90 * Math.PI / 180;
|
||||
|
||||
return mesh;
|
||||
};
|
||||
}());
|
|
@ -3,7 +3,31 @@
|
|||
"use strict";
|
||||
|
||||
VIZI.BuildingManager = function() {
|
||||
// Extend Object class
|
||||
VIZI.Log("Inititialising building manager");
|
||||
|
||||
VIZI.ObjectManager.call(this);
|
||||
};
|
||||
|
||||
VIZI.BuildingManager.prototype = Object.create( VIZI.ObjectManager.prototype );
|
||||
|
||||
VIZI.BuildingManager.prototype.process = function(data) {
|
||||
VIZI.Log("Processing buildings");
|
||||
|
||||
var features = data.features;
|
||||
var objects = _.map(features, this.processFeature);
|
||||
|
||||
this.combinedObjects = this.combineObjects(objects);
|
||||
|
||||
this.publish("addToScene", this.combinedObjects);
|
||||
};
|
||||
|
||||
VIZI.BuildingManager.prototype.processFeature = function(feature) {
|
||||
switch (feature.type) {
|
||||
case "Feature":
|
||||
return new VIZI.Building(feature);
|
||||
default:
|
||||
VIZI.Log("Unable to process building of type: " + feature.type);
|
||||
return;
|
||||
}
|
||||
};
|
||||
}());
|
|
@ -5,12 +5,13 @@
|
|||
VIZI.Floor = function() {
|
||||
VIZI.Log("Inititialising floor object");
|
||||
|
||||
// Extend Object class
|
||||
VIZI.Object.call(this);
|
||||
|
||||
this.object = this.createObject();
|
||||
};
|
||||
|
||||
VIZI.Floor.prototype = Object.create( VIZI.Object.prototype );
|
||||
|
||||
VIZI.Floor.prototype.createObject = function() {
|
||||
var floorContainer = new THREE.Object3D();
|
||||
|
||||
|
|
|
@ -4,7 +4,27 @@
|
|||
|
||||
VIZI.Object = function() {
|
||||
_.extend(this, VIZI.Mediator);
|
||||
|
||||
this.geo = VIZI.Geo.getInstance();
|
||||
};
|
||||
|
||||
VIZI.Object.prototype.createObject = function() {};
|
||||
|
||||
VIZI.Object.prototype.createShapeFromCoords = function(coords) {
|
||||
var self = this;
|
||||
var shape = new THREE.Shape();
|
||||
|
||||
_.each(coords, function(element, index) {
|
||||
var projectedCoords = self.geo.projection(element);
|
||||
|
||||
// Move if first coordinate
|
||||
if (index === 0) {
|
||||
shape.moveTo( projectedCoords[0], projectedCoords[1] );
|
||||
} else {
|
||||
shape.lineTo( projectedCoords[0], projectedCoords[1] );
|
||||
}
|
||||
});
|
||||
|
||||
return shape;
|
||||
};
|
||||
}());
|
|
@ -1,16 +1,46 @@
|
|||
/* globals window, _, VIZI, THREE, Q */
|
||||
/* globals window, _, VIZI, THREE, Q, d3 */
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
VIZI.ObjectManager = function() {
|
||||
_.extend(this, VIZI.Mediator);
|
||||
|
||||
this.objects = [];
|
||||
|
||||
this.combinedMaterial = new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors});
|
||||
this.combinedObjects = undefined;
|
||||
};
|
||||
|
||||
VIZI.ObjectManager.prototype.load = function(url) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
// JSON load stuffs
|
||||
d3.json(url, function(error, data) {
|
||||
if (error) {
|
||||
deferred.reject(new Error(error));
|
||||
} else {
|
||||
deferred.resolve(data);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
VIZI.ObjectManager.prototype.process = function(objects) {};
|
||||
VIZI.ObjectManager.prototype.processFeature = function(feature) {};
|
||||
|
||||
VIZI.ObjectManager.prototype.combineObjects = function(objects) {
|
||||
var combinedGeom = new THREE.Geometry();
|
||||
|
||||
_.each(objects, function(object) {
|
||||
if (!object.object) {
|
||||
return;
|
||||
}
|
||||
|
||||
THREE.GeometryUtils.merge(combinedGeom, object.object);
|
||||
});
|
||||
|
||||
combinedGeom.computeFaceNormals();
|
||||
|
||||
return new THREE.Mesh( combinedGeom, this.combinedMaterial );
|
||||
};
|
||||
}());
|
|
@ -65,4 +65,19 @@
|
|||
this.lights.push(hemiLight);
|
||||
this.publish("addToScene", hemiLight);
|
||||
};
|
||||
|
||||
// Global helpers (move elsewhere?)
|
||||
VIZI.applyVertexColors = function( g, c ) {
|
||||
g.faces.forEach( function( f ) {
|
||||
|
||||
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
|
||||
|
||||
for( var j = 0; j < n; j ++ ) {
|
||||
|
||||
f.vertexColors[ j ] = c;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
};
|
||||
}());
|
Plik diff jest za duży
Load Diff
Ładowanie…
Reference in New Issue