0.2
Robin Hawkes 2016-06-09 16:41:47 -07:00
commit a4465482c3
175 zmienionych plików z 67630 dodań i 63923 usunięć

58
.gitignore vendored
Wyświetl plik

@ -1,5 +1,59 @@
node_modules
build
### ViziCities ###
bower_components
src/UI/*.js
# Created by https://www.gitignore.io
### Node ###
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules
# Users Environment Variables
.lock-wscript
### OSX ###
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

Wyświetl plik

@ -4,11 +4,9 @@ node_js:
before_install:
- npm install -g grunt-cli
notifications:
irc: "chat.eu.freenode.net#vizicities"
webhooks:
urls:
- http://surveyor-hubot.apps.rawk.es/hubot/travis?room=%23vizicities
- https://vizicities.slack.com/services/hooks/travis?token=RGVKvriXw709tZ496MfHw34a
- secure: "v5qUk/Zl6w9wJKkjtmCZahLPVo/PaJ3LloFsCD2Lzhy08lR2RrC1SRixHdElEYpHk/KipBGAW/AwwLglvMjWmQsABA++TvbEoeb5KlWOouRFMvADbP4zHYvGx/gJGcFW+djsdMexHb4FTUtYfEyDpEC00FTUPbyOdxu6p00cJCY="
on_success: always
on_failure: always
on_start: true

Wyświetl plik

@ -11,13 +11,13 @@ There are multiple ways you can help:
## Raising issues
The majority of contributions will come from bug reports and feature requests. Please read the following guidelines so things can happen as quickly and smoothly as possible. Also, it's a good idea to [use the right tags](https://github.com/robhawkes/vizicities/wiki/Which-issue-tags-to-use-and-when/) when creating an issue.
The majority of contributions will come from bug reports and feature requests. Please read the following guidelines so things can happen as quickly and smoothly as possible. Also, it's a good idea to [use the right tags](https://github.com/vizicities/vizicities/wiki/Which-issue-tags-to-use-and-when/) when creating an issue.
In general, make sure that you [search for existing issues](https://github.com/robhawkes/vizicities/issues) and discussions __before__ posting something new. Dealing with unnecessary duplication takes valuable time away from working on the project. If in doubt, [post something in the ViziCities Google Group](https://groups.google.com/forum/#!forum/vizicities).
In general, make sure that you [search for existing issues](https://github.com/vizicities/vizicities/issues) and discussions __before__ posting something new. Dealing with unnecessary duplication takes valuable time away from working on the project. If in doubt, [post something in the ViziCities Google Group](https://groups.google.com/forum/#!forum/vizicities).
### Bug reports
Found something wrong with an existing feature? [Submit a bug report](https://github.com/robhawkes/vizicities/issues/new) so it can be fixed.
Found something wrong with an existing feature? [Submit a bug report](https://github.com/vizicities/vizicities/issues/new) so it can be fixed.
If you follow the template below then you'll make everyone really happy.
@ -48,35 +48,35 @@ reported. Especially, why do you consider this to be a bug? What do you expect t
### Feature requests
Got an idea for a new feature? Awesome! Double-checked to make sure it hasn't already been suggested? Even more awesome! Now you're ready to [submit a feature request](https://github.com/robhawkes/vizicities/issues/new). Make sure to provide as much detail as possible, focussing particularly on why this feature is needed (bonus points for example uses).
Got an idea for a new feature? Awesome! Double-checked to make sure it hasn't already been suggested? Even more awesome! Now you're ready to [submit a feature request](https://github.com/vizicities/vizicities/issues/new). Make sure to provide as much detail as possible, focussing particularly on why this feature is needed (bonus points for example uses).
If your idea isn't fully fleshed out yet then hold off on the feature request and [start a new topic in the ViziCities Google Group](https://groups.google.com/forum/#!forum/vizicities) — we'll put our heads together.
### Change requests
Not happy with an existing feature, or think something could be tweaked? Check that it hasn't already been suggested and then [submit a change request](https://github.com/robhawkes/vizicities/issues/new).
Not happy with an existing feature, or think something could be tweaked? Check that it hasn't already been suggested and then [submit a change request](https://github.com/vizicities/vizicities/issues/new).
## Submitting code to ViziCities
If you want to submit code to the project, perhaps on one of the new features, then you can do so [via a pull request](https://github.com/robhawkes/vizicities/pulls). We're pretty relaxed about the process for now, though we'll be implementing testing and procedure as the project matures.
If you want to submit code to the project, perhaps on one of the new features, then you can do so [via a pull request](https://github.com/vizicities/vizicities/pulls). We're pretty relaxed about the process for now, though we'll be implementing testing and procedure as the project matures.
Bear in mind the following to help things go smoothly and quickly:
* Pull requests that don't relate to [an existing issue](https://github.com/robhawkes/vizicities/issues) will be ignored or put to the back of the queue
* Pull requests that don't relate to [an existing issue](https://github.com/vizicities/vizicities/issues) will be ignored or put to the back of the queue
* Submitted code should be clean (no mess) and roughly follow the coding conventions of the project
* Submitted code should not break an existing feature
If in doubt, [talk to us](https://github.com/robhawkes/vizicities#contact--community) and we'll help you through it.
If in doubt, [talk to us](https://github.com/vizicities/vizicities#contact--community) and we'll help you through it.
## Contributor license agreement
__TL;DR: If you contribute to ViziCities then you accept that your work will become part of an MIT-licensed project and therefore may also be used on a for-profit basis. You should also have all rights to the work you contribute.__
By contributing your code to ViziCities you grant ViziCities (Robin Hawkes) a non-exclusive, irrevocable, worldwide, royalty-free, sublicenseable, transferable license under all of Your relevant intellectual property rights (including copyright, patent, and any other rights), to use, copy, prepare derivative works of, distribute and publicly perform and display the Contributions on any licensing terms, including without limitation: (a) open source licenses like the MIT license; and (b) binary, proprietary, or commercial licenses. Except for the licenses granted herein, You reserve all right, title, and interest in and to the Contribution.
By contributing your code to ViziCities you grant ViziCities a non-exclusive, irrevocable, worldwide, royalty-free, sublicenseable, transferable license under all of Your relevant intellectual property rights (including copyright, patent, and any other rights), to use, copy, prepare derivative works of, distribute and publicly perform and display the Contributions on any licensing terms, including without limitation: (a) open source licenses like the MIT license; and (b) binary, proprietary, or commercial licenses. Except for the licenses granted herein, You reserve all right, title, and interest in and to the Contribution.
You confirm that you are able to grant us these rights. You represent that You are legally entitled to grant the above license. If Your employer has rights to intellectual property that You create, You represent that You have received permission to make the Contributions on behalf of that employer, or that Your employer has waived such rights for the Contributions.
You represent that the Contributions are Your original works of authorship, and to Your knowledge, no other person claims, or has the right to claim, any right in any invention or patent related to the Contributions. You also represent that You are not legally obligated, whether by entering into an agreement or otherwise, in any way that conflicts with the terms of this license.
ViziCities (Robin Hawkes) acknowledges that, except as explicitly described in this Agreement, any Contribution which you provide is on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
ViziCities acknowledges that, except as explicitly described in this Agreement, any Contribution which you provide is on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.

Wyświetl plik

@ -1,16 +0,0 @@
# Data formats for ViziCities features
* How to format data to be read correctly by ViziCities
* GeoJSON / TopoJSON with the following attributes (eg. height, etc)
## Buildings
```
{}
```
## Roads
```
{}
```

Wyświetl plik

@ -1,165 +1,149 @@
// TODO: Automatically update/install bower components on build
// - https://github.com/rse/grunt-bower-install-simple
// TODO: Smash D3 into only the neccessary components
// - https://github.com/mbostock/smash/wiki
// - https://github.com/cvisco/grunt-smash
// TODO: Add code style tests
// - https://github.com/jscs-dev/node-jscs
// TODO: Make React compilation dynamic
module.exports = function(grunt) {
var port = grunt.option('port') || 8000;
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
react: {
vizicities: {
files: [{
"src/UI/LayersUI.js": "src/UI/LayersUI.jsx"
}, {
"src/UI/KeyUIColourScale.js": "src/UI/KeyUIColourScale.jsx"
}, {
"src/UI/InfoUI2D.js": "src/UI/InfoUI2D.jsx"
}, {
"src/UI/DescriptionUI.js": "src/UI/DescriptionUI.jsx"
}]
}
},
uglify: {
vizicities: {
options: {
banner: "/*! ViziCities - v<%= pkg.version %> - " +
"<%= grunt.template.today('yyyy-mm-dd') %> */\n",
beautify : {
ascii_only : true
}
},
files: {
"build/vizi.min.js": ["build/vizi.js"]
}
},
vizicities_worker: {
options: {
banner: "/*! ViziCities - v<%= pkg.version %> - " +
"<%= grunt.template.today('yyyy-mm-dd') %> */\n",
beautify : {
ascii_only : true
}
},
files: {
"build/vizi-worker.min.js": ["build/vizi-worker.js"]
}
}
},
concat: {
vizicities: {
src: ["src/Vizi.js", "src/Core/*.js", "src/Geo/CRS.js", "src/WebGL/*.js", "src/Controls/Controls.js", "src/UI/*.js", "src/**/*.js"],
dest: "build/vizi.js"
},
bower: {
options: {
stripBanners: true,
banner: "/*! ViziCities - v<%= pkg.version %> - " +
"<%= grunt.template.today('yyyy-mm-dd') %> */\n"
},
src: ["bower_components/**/*min.js", "bower_components/proj4/dist/proj4-src.js", "bower_components/wildemitter/wildemitter-bare.js", "build/vizi.js", "!bower_components/react/react-with-addons.min.js"],
dest: "build/vizi.js"
},
bower_min: {
src: ["bower_components/**/*min.js", "bower_components/proj4/dist/proj4.js", "bower_components/wildemitter/wildemitter-bare.js", "build/vizi.min.js", "!bower_components/react/react-with-addons.min.js"],
dest: "build/vizi.min.js"
},
vizicities_worker: {
src: ["src/Vizi.js", "src/Geo/CRS.js", "src/Geo/**/*.js", "src/Geometry/**/*.js"],
dest: "build/vizi-worker.js"
},
bower_worker: {
options: {
stripBanners: true,
banner: "/*! ViziCities - v<%= pkg.version %> - " +
"<%= grunt.template.today('yyyy-mm-dd') %> */\n"
},
src: ["bower_components/underscore/*min.js", "bower_components/threejs/**/*min.js", "bower_components/proj4/dist/proj4-src.js", "build/vizi-worker.js"],
dest: "build/vizi-worker.js"
},
bower_worker_min: {
src: ["bower_components/underscore/*min.js", "bower_components/threejs/**/*min.js", "bower_components/proj4/dist/proj4-src.js", "build/vizi-worker.min.js"],
dest: "build/vizi-worker.min.js"
},
},
jshint: {
options: {
force: true,
curly: false,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
eqnull: true,
browser: true,
expr: true,
globals: {
head: false,
module: false,
console: false,
importScripts: true
},
ignores: ["src/vendor/**"]
},
files: ["src/**"]
},
mocha_slimer: {
options: {
xvfb: (process.env.TRAVIS === "true"),
reporter: "Dot",
timeout: 60000,
run: true
},
all: {
options: {
ui: "bdd",
reporter: "Spec",
run: true
},
src: ["test/*.html"]
}
}
});
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! ViziCities <%= grunt.template.today("yyyy-mm-dd") %> */\n',
beautify : {
ascii_only : true
}
},
build: {
src: 'build/vizi.js',
dest: 'build/vizi.min.js'
}
},
concat: {
options: {},
dist: {
// src: ['src/shared/vendor/underscore.js', 'src/shared/vendor/three.js', 'src/client/*'],
src: [
'src/shared/vendor/underscore.js',
'src/shared/vendor/q.js',
'src/shared/vendor/three/three.js',
'src/shared/vendor/three/ColorConverter.js',
'src/shared/vendor/d3.js',
'src/shared/vendor/catiline.js',
'src/shared/vendor/dat.gui.js',
'src/shared/vendor/fpsmeter.js',
'src/shared/vendor/moment.js',
'src/shared/vendor/simplify.js',
'src/shared/vendor/throat.js',
'src/client/Vizi.js',
'src/client/Log.js',
'src/client/Mediator.js',
'src/client/Animation.js',
'src/client/debug/Dat.js',
'src/client/debug/FPS.js',
'src/client/debug/RendererInfo.js',
'src/client/ui/Loading.js',
'src/client/ui/Attribution.js',
'src/client/ui/OSMEdit.js',
'src/client/Geo.js',
'src/client/City.js',
'src/client/Loop.js',
'src/client/DOMEvents.js',
'src/client/webgl/WebGL.js',
'src/client/webgl/Scene.js',
'src/client/webgl/Camera.js',
'src/client/webgl/Renderer.js',
'src/client/objects/ObjectManager.js',
'src/client/objects/ObjectManagerOverpass.js',
'src/client/objects/Object.js',
'src/client/objects/Floor.js',
'src/client/data/Data.js',
'src/client/data/DataOverpass.js',
'src/client/Grid.js',
'src/client/controls/Mouse.js',
'src/client/controls/Keyboard.js',
'src/client/controls/Controls.js',
'src/client/Cache.js'
],
dest: 'build/vizi.js'
}
},
jshint: {
options: {
force: true,
curly: false,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
eqnull: true,
browser: true,
expr: true,
globals: {
head: false,
module: false,
console: false,
importScripts: true
},
ignores: ['src/shared/vendor/**']
},
files: [ 'Gruntfile.js', 'src/**' ]
},
mocha_phantomjs: {
files: ['test/*.html']
},
watch: {
main: {
files: [ 'Gruntfile.js', 'src/**', 'examples/**' ],
tasks: 'default',
options: {
livereload: 35730
}
}
},
connect: {
server: {
options: {
port: port,
// change hostname to 0.0.0.0 to open it up
hostname: 'localhost',
base: '.',
keepalive: true,
debug: true
}
}
},
notify: {
watch: {
options: {
// title: 'Watching files', // optional
message: 'Watching for changes' //required
}
},
finish: {
options: {
// title: 'Watching files', // optional
message: 'Build complete' //required
}
}
},
notify_hooks: {
options: {
enabled: true,
max_jshint_notifications: 5,
title: "ViziCities"
}
}
});
// Load the plugins
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-mocha-slimer");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-react");
// Load the plugins
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-notify');
grunt.loadNpmTasks('grunt-mocha-phantomjs');
// Default task(s).
grunt.registerTask("default", ["test"]);
// Default task(s).
// grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'notify:finish']);
grunt.registerTask('default', ['jshint', 'concat', 'notify:finish']);
// Testing
// TODO: If tests keep failing randomly on Travis then move back to Phantom
// - Just means absolute zero chance of WebGL testing then
grunt.registerTask("test", ["jshint", "mocha_slimer"]);
// Serve examples locally
grunt.registerTask('serve', ['connect']);
// Build files and refresh content on file changes
grunt.registerTask('dev', ['default', 'notify:watch', 'watch']);
// Minify
grunt.registerTask('min', ['jshint', 'concat', 'uglify', 'notify:finish']);
// Run tests
grunt.registerTask('test', ['jshint', 'mocha_phantomjs']);
grunt.task.run('notify_hooks');
// Build
grunt.registerTask("build", ["react:vizicities", "concat:vizicities", "uglify:vizicities", "concat:bower", "concat:bower_min"]);
grunt.registerTask("build_worker", ["react", "concat:vizicities_worker", "uglify:vizicities_worker", "concat:bower_worker", "concat:bower_worker_min"]);
};

318
README.md
Wyświetl plik

@ -1,169 +1,271 @@
# ViziCities [0.1.0-pre] [![Build Status](https://travis-ci.org/vizicities/vizicities.png?branch=master)](https://travis-ci.org/vizicities/vizicities)
__Bringing cities to life using the power of open data and the Web__
# ViziCities 0.2.0 [Codename: Hamlet] [![Build Status](https://travis-ci.org/vizicities/vizicities.png?branch=0.2.0)](https://travis-ci.org/vizicities/vizicities)
__JavaScript 3D city and data visualisation platform__
![http://vizicities.apps.rawk.es](http://cl.ly/VS9H/Screen%20Shot%202014-05-10%20at%2016.04.54.png)
[![](http://cl.ly/VS9H/Screen%20Shot%202014-05-10%20at%2016.04.54.png)](http://vizicities.com)
[ViziCities](http://vizicities.com) is a 3D city and data visualisation platform, powered by WebGL. Its purpose is to change the way you look at cities and the data contained within them.
### Demonstration
**Important links**
Here's a [demo of ViziCities](http://vizicities.apps.rawk.es) so you can have a play without having to build it for yourself. Cool, ey?
### What does it do?
ViziCities aims to combine data visualisation with a 3D representation of a city to provide a better understanding what's going on. It's a powerful new way of looking at and understanding urban areas.
Aside from seeing a city in 3D, here are some of the others things you'll have the power to do:
* View public transport (eg. buses, trains, planes) [flowing around a city in realtime](https://vimeo.com/67869313)
* Use vehicles powered by artificial intelligence to [perform realistic traffic simulation](https://vimeo.com/66512057)
* Visualise [social data in realtime](https://vimeo.com/67872925)
* Overlay historic and static data (eg. census data) using traditional techniques (eg. heatmaps)
* And much more&hellip;
* Play with an [interactive demo of ViziCities](http://rawgit.com/vizicities/vizicities/0.2.0/examples/basic-example/index.html)
* Find out more about what you can do with ViziCities [on the website](http://vizicities.com)
* Read [the documentation](http://dev.vizicities.com) and learn how to make something with ViziCities
### Further information
## Quick install
For more information you should start here:
Already know what you're doing? Awesome! ViziCities is [installable through Bower](http://bower.io/) so you can quickly get up and running.
* [ViziCities website](http://vizicities.com)
* [ViziCities announcement article](http://rawkes.com/articles/vizicities-dev-diary-1)
* [Videos of various ViziCities experiments](https://vimeo.com/channels/vizicities)
```bash
$ bower install -p vizicities
```
## Features
ViziCities is currently in a pre-alpha state, meaning things are changing rapidly and you should expect bugs.
## ViziCities examples
### 0.1.0-pre
Here are some examples of ViziCities and how it's being used to help people.
* Load anywhere in the world using coordinates in the URL (#lat,lon) ([like Oslo](http://vizicities.apps.rawk.es/demo.html#59.913869,10.752245))
* Buildings, water (rivers, canals, etc), and green areas (parks, grass, forest, etc)
* Dynamic data loading using the OpenStreetMap Overpass API (literally the entire world)
* Accurate heights based on OpenStreetMap tags, if available
* Loading of data using a TMS grid system
* Caching of loaded grid data to prevent duplicated requests
* Processing of geographic features into 3D objects using Web Workers
* Controls (zoom, pan and orbit)
* Basic tests and build status using Travis CI
* Grunt-based development environment
* [Data journalism piece](http://interaktiv.morgenpost.de/tempelhofer-feld/) from the Beliner Morgenpost
### Future features
**Built something with ViziCities?** [Get in touch](hello@vizicities.com), we'd love to showcase it here for everyone else to see and learn from.
## Changes since 0.1.0-pre
Numerous lessons were learnt after releasing 0.1.0-pre to the public, so much so that the decision was made to start from the beginning and get things right. 0.2.0 is the first attempt at that, a complete rewrite from the ground up. There are some pretty major differences!
### Blueprint API
Data input and visualisation output is now controlled by the [Blueprint API](http://dev.vizicities.com/v0.2.0/docs/using-the-blueprint-api). It's based on the concept of triggers and actions; much like Zapier or IFTTT, just instead for geographic data visualisation. It underpins the entire system for 0.2.0 and it completely changes the way you pull data into ViziCities and how you output it. A lot of hard work went into formulating and constructing it &mdash; we're incredibly proud of it!
In short, the Blueprint API has 3 parts; an input, an output and a mapping configuration. Neither the input nor the output know about each other or care about each others data structure. Everything is neatly brought together by a configuration object that describes which input to use, which output to use, as well as how and, more importantly, when to map the data between them.
It's an incredibly powerful and extensible system and we can't wait to see what you build with it. We're also looking forward to you contributing new inputs and outputs for others to benefit from.
By default, ViziCites now supports:
* Dynamic base maps using standard tile-server URLs (eg. Mapbox)
* GeoJSON input
* Basic KML input (only points so far)
* Collada output
* Choropleth (heatmap-like) output
* Dynamic building output from a vector tile source ([like Mapzen](https://github.com/mapzen/vector-datasource/wiki/Mapzen-Vector-Tile-Service))
Make sure to read the [documentation on the Blueprint API](http://dev.vizicities.com/v0.2.0/docs/using-the-blueprint-api) to learn how to use it.
### Easier setup and customisation
It's now much easier to set up and customise ViziCities. It was clear that 0.1.0-pre was far too prescriptive about how to use the system, so an effort has been made to allow customisation via options or overriding of default functionality. Combined with the Blueprint API, you now have full control over the data and visualisations you want to use.
A result of these changes means that setting up ViziCities is different to how you're used to from 0.1.0-pre. It's worth [reading the documentation](http://dev.vizicities.com) to see how much easier and better things have become.
### Vastly improved controls
The control system has received a lot of love since 0.1.0-pre and, aside from being smoother, it now allow you to use multiple methods of control at once. Right now there are just a few to choose from but this number will grow as new systems are contributed. It's also worth mentioning that the view angle caps in 0.1.0 have been removed &mdash; you can now look wherever you want!
### Other stuff
* More robust and flexible coordinate projection system
* Synchronous update and render loop
* Improved event system
* Simpler file and directory structure
* ViziCities Bower package
* Ready-to-use build of ViziCities in the `build` directory
* Testing across 100% of the core system
* Improved Grunt build process
* 3D road network
* Static data visualisation layers (heatmaps, bar charts, etc)
* Live data visualisation (tweets, public transport, etc)
* AI vehicles and pedestrians
* Local weather
* Post processing (DoF, SSAO, etc)
* 3D terrain
* And much more&hellip;
## Known issues
ViziCities is not complete and there are likely many things that could be done better or simply need fixing. Here is a list of the major known issues:
ViziCities is not complete and there are many things that could be done better or simply need fixing. Here is a list of the major known issues:
* Data isn't cached right now
* There's no post processing (eg. ambient occlusion, etc)
* Lighting cannot be easily customised
* Performance can be improved in areas
* Not all features from OpenStreetMap are being displayed (particularly relations)
* Performance of tile-based loading mechanism is poor
* Web Worker processing isn't efficient due to the way scripts and data are loaded
* Caching is reset on page reload
* XHR requests for data can take some time, causing visible delay
* Performance issues with dense cities (eg. NYC)
## Getting started
ViziCities is at an incredibly early stage right now, but it's usable if you know what you're doing. The following steps should get you up and running without too much trouble.
Here are some step-by-step instructions on how to get up and running with your first visualisation, a 3D basemap. You can also [use this JSBin](http://jsbin.com/qaqogo/2/edit?html,js,output) to see the example running and play with the code.
### Building ViziCities
The first step is to download the [latest ViziCities build files](https://github.com/vizicities/vizicities/tree/0.2.0/build) (JS & CSS).
To start off, you'll need to build ViziCities and get an up-to-date JavaScript file.
Once you've done that then set up the basic HTML and include the ViziCities files:
#### Clone the ViziCities repo
```html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ViziCities - Basic Example</title>
```
git clone https://github.com/vizicities/vizicities.git vizicities
<style type="text/css">
html, body {
height: 100%;
width: 100%;
}
#vizicities-viewport {
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" type="text/css" href="vizi.css">
</head>
<body>
<div id="vizicities-viewport"></div>
<script src="vizi.min.js"></script>
<script src="main.js"></script>
</body>
</html>
```
#### [Install Node.js & NPM](http://nodejs.org/)
If you haven't already, [install Homebrew](http://brew.sh/) before going any further.
At this point you can initialise ViziCities in a new script (`main.js` in this example):
```
brew install node
```
#### [Install the Grunt CLI](http://gruntjs.com/getting-started)
```
npm install -g grunt-cli
```javascript
var world = new VIZI.World({
viewport: document.querySelector("#vizicities-viewport"),
center: new VIZI.LatLon(51.50358, -0.01924)
});
```
#### Install the NPM packages
```
cd /path/to/vizicities
npm install
And add some controls:
```javascript
var controls = new VIZI.ControlsMap(world.camera, {
viewport: world.options.viewport
});
```
#### Build ViziCities and watch for file changes using Grunt
```
cd /path/to/vizicities
grunt dev
Let's add a basemap using the Blueprint API:
```javascript
var mapConfig = {
input: {
type: "BlueprintInputMapTiles",
options: {
tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
}
},
output: {
type: "BlueprintOutputImageTiles",
options: {
grids: [{
zoom: 13,
tilesPerDirection: 5,
cullZoom: 11
}]
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "output",
triggerName: "gridUpdated",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "input",
triggerName: "tileReceived",
triggerArguments: ["image", "tile"],
actionObject: "output",
actionName: "outputImageTile",
actionArguments: ["image", "tile"],
actionOutput: {
image: "image", // actionArg: triggerArg
tile: "tile"
}
}]
};
var switchboardMap = new VIZI.BlueprintSwitchboard(mapConfig);
switchboardMap.addToWorld(world);
```
#### Serve examples using Grunt
Open a new terminal tab or window, then type:
The last step is to to set up the update and render loop:
```
cd /path/to/vizicities
grunt serve
```javascript
var clock = new VIZI.Clock();
var update = function() {
var delta = clock.getDelta();
world.onTick(delta);
world.render();
window.requestAnimationFrame(update);
};
update();
```
Then open [http://localhost:8000/examples](http://localhost:8000/examples)
Load the HTML page in a browser and enjoy your awesome 3D view of London!
### Using ViziCities
## Using ViziCities? Please attribute it
Use the [built in example](https://github.com/vizicities/vizicities/tree/master/examples) to get an idea of what ViziCities can do. Change the coordinates to load a new part of the world (anywhere you want).
While we love giving you the code to ViziCities for free, we also appreciate getting some recognition for all the hard work that's gone into it. A small, inconspicuous attribution is built into ViziCities and, while possible to remove, we'd really appreciate it if you left it in.
If you really need to remove the attribution, please [get in touch](hello@vizicities.com) and we can work out an alternative.
## Forked ViziCities 0.1.0-pre? Update your remote URL
The ViziCities repo has been moved away from Robin's personal account and now resides within the UDST organisation on GitHub. As a result of this, you'll need to update the remote URL if you've forked ViziCities in the past.
It's pretty easy to do, [GitHub even wrote about how to do it](https://help.github.com/articles/changing-a-remote-s-url/). Running the following command within your ViziCities directory should be enough for most people:
```bash
$ git remote set-url origin git@github.com:UDST/vizicities.git
```
## Getting involved
ViziCities can't happen without your help. We need people to submit bugs, suggest features, share how they're using the project, and contribute code. Sound like you? [Check out exactly how to get involved](https://github.com/vizicities/vizicities/blob/master/CONTRIBUTING.md).
### Suggestions
There are a couple of things in particular that need your help:
* Styling improvements (play with the lighting and materials, add shaders, make things look pretty)
* Performance improvements (particularly with feature processing, generation and rendering)
## Contact & community
Communicate with the ViziCities team via email ([hello@vizicities.com](mailto:hello@vizicities.com)) and Twitter ([@ViziCities](http://twitter.com/ViziCities)). All other discussion should happen in the [ViziCities Google Group](https://groups.google.com/forum/#!forum/vizicities), IRC (#vizicities on Freenode) or [relevant GitHub issues page](https://github.com/vizicities/vizicities/issues).
Communicate with the ViziCities team via email ([hello@vizicities.com](mailto:hello@vizicities.com)) and Twitter ([@ViziCities](http://twitter.com/ViziCities)). All other discussion should happen in the [ViziCities Google Group](https://groups.google.com/forum/#!forum/vizicities) or [relevant GitHub issues page](https://github.com/vizicities/vizicities/issues).
## Libraries and resources used
## Libraries used
* [OpenStreetMap](http://openstreetmap.org) – Map data
* [Three.js](http://threejs.org) – WebGL
* [D3.js](http://d3js.org) – Geographic coordinate conversion
* [Underscore.js](http://underscorejs.org) – General helpers
* [Q](https://github.com/kriskowal/q) – Promises
* [Throat](https://github.com/ForbesLindesay/throat) - Limiting concurrency
* [Catiline](http://catilinejs.com) – Web Workers
* [Dat.gui](https://code.google.com/p/dat-gui) – Debug control panel
* [FPSMeter](http://darsa.in/fpsmeter) – FPS meter
* [Moment.js](http://momentjs.com) – Date processing
* [Simplify.js](http://mourner.github.io/simplify-js) – Polygon simplification
* [Proj4js](https://github.com/proj4js/proj4js) – Geographic coordinate projection
* [WildEmitter](https://github.com/HenrikJoreteg/wildemitter) - Event system
* [Underscore.js](http://underscorejs.org) – General JavaScript helpers
* [D3.js](http://d3js.org) – Data visualisation helpers
* [Operative](https://github.com/padolsey/operative) – Web Workers
* [Mocha](https://github.com/mochajs/mocha) - Testing framework
* [Chai](http://chaijs.com/) - Test assertions
* [Bower](http://bower.io/) – Packaging system
* [Grunt](http://gruntjs.com) – Build system
## FAQ
## Copyright & license
### What happened to all the cool features I saw in the blog posts?
The MIT License (MIT)
Over the past year [we've been producing experiments](http://rawkes.com/articles/vizicities-dev-diary-2) to prove that ViziCities is possible. These experiments, while working, were not robust and never intended for release. The version of ViziCities you see here is a solid foundation based on the lessons learnt from the previous experiments. It will eventually catch up with those experiments in regards to features.
Copyright (c) 2014 - Robin Hawkes
### What are the controls?
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* Zoom using the mouse wheel
* Pan using the left mouse button
* Orbit by holding shift and using the left mouse button, or using the middle mouse button
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

49
bower.json 100644
Wyświetl plik

@ -0,0 +1,49 @@
{
"name": "vizicities",
"version": "0.2.0",
"authors": [
"Robin Hawkes <rob@vizicities.com>"
],
"description": "3D city and data visualisation platform",
"main": [
"build/vizi.min.js",
"build/vizi-worker.min.js",
"build/vizi.js",
"build/vizi-worker.js",
"build/vizi.css"
],
"keywords": [
"mapping",
"geography",
"cities",
"urban",
"data",
"dataviz",
"3d"
],
"license": "MIT",
"homepage": "http://vizicities.com",
"ignore": [
"**/.*",
"*.md",
"Gruntfile.js",
"package.json",
"node_modules",
"bower_components",
"examples",
"src",
"test",
"tests"
],
"devDependencies": {
"underscore": "~1.7.0",
"threejs": "*",
"wildemitter": "HenrikJoreteg/wildemitter#~1.0.1",
"proj4": "~2.3.3",
"d3": "~3.4.13",
"operative": "https://github.com/padolsey/operative/archive/0-4-rc1.zip"
},
"dependencies": {
"react": "~0.12.2"
}
}

6710
build/vizi-worker.js 100644

File diff suppressed because one or more lines are too long

6281
build/vizi-worker.min.js vendored 100644

File diff suppressed because one or more lines are too long

181
build/vizi.css 100644
Wyświetl plik

@ -0,0 +1,181 @@
.vizicities-attribution {
background: rgba(255, 255, 255, 0.9);
border-radius: 3px 0 0;
bottom: 0;
color: #666;
font-family: Arial, Verdana, sans-serif;
font-size: 11px;
padding: 4px 7px;
position: absolute;
right: 0;
z-index: 9998;
}
.vizicities-attribution a, .vizicities-attribution a:visited {
color: #2bb2ed;
text-decoration: none;
}
.vizicities-attribution a:hover {
color: #2bb2ed;
text-decoration: underline;
}
.vizicities-ui {
height: 100%;
overflow: hidden;
position: absolute;
pointer-events: none;
z-index: 9998;
width: 100%;
}
.vizicities-ui .vizicities-ui-item header {
background: #222;
border-radius: 3px 3px 0 0;
color: #fff;
}
.vizicities-ui .vizicities-ui-item header:hover {
cursor: pointer;
}
.vizicities-ui .vizicities-ui-item.closed header {
border-radius: 3px;
}
.vizicities-ui .vizicities-ui-item h2 {
font-size: 16px;
font-weight: normal;
margin: 0;
padding: 12px 15px 10px;
text-transform: uppercase;
}
.vizicities-ui .vizicities-layers-ui {
display: absolute;
}
.vizicities-ui .vizicities-layers-ui-item {
background: #fff;
border-radius: 3px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
font-family: Arial, Verdana, sans-serif;
font-size: 16px;
pointer-events: auto;
position: absolute;
right: 20px;
top: 20px;
width: 200px;
}
.vizicities-ui .vizicities-layers-ui-item ul {
list-style: none;
margin: 0;
padding: 10px 0 10px;
}
.vizicities-ui .vizicities-layers-ui-item.closed ul {
display: none;
}
.vizicities-ui .vizicities-layers-ui-item li {
margin: 0;
padding: 5px 15px;
}
.vizicities-ui .vizicities-layers-ui-item li input {
vertical-align: text-bottom;
}
.vizicities-ui .vizicities-key-ui {
display: absolute;
}
.vizicities-ui .vizicities-key-ui-item {
background: #fff;
border-radius: 3px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
font-family: Arial, Verdana, sans-serif;
font-size: 16px;
pointer-events: auto;
position: absolute;
left: 20px;
top: 20px;
width: 200px;
}
.vizicities-ui .vizicities-key-ui-item ul {
list-style: none;
margin: 0;
padding: 10px 0 10px;
}
.vizicities-ui .vizicities-key-ui-item.closed ul {
display: none;
}
.vizicities-ui .vizicities-key-ui-item li {
margin: 0;
padding: 5px 15px;
}
.vizicities-ui .vizicities-key-ui-item li.description {
font-size: smaller;
font-style: italic;
}
.vizicities-ui .vizicities-key-ui-item li span.scale-icon {
border-radius: 5px;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.4);
display: inline-block;
height: 10px;
margin-right: 5px;
width: 10px;
}
.vizicities-ui .vizicities-info-ui-2d-layer {
display: absolute;
}
.vizicities-ui .vizicities-info-ui-2d-layer-item {
background: #222;
border-radius: 3px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
color: #fff;
font-family: Helvetica Neue, Arial, Verdana, sans-serif;
font-size: 12px;
font-weight: 200;
letter-spacing: 1px;
margin-top: -40px;
padding: 6px 8px;
position: absolute;
text-align: center;
text-transform: uppercase;
}
.vizicities-ui .vizicities-description-ui {
display: absolute;
}
.vizicities-ui .vizicities-description-ui-item {
background: #fff;
border-radius: 3px;
bottom: 20px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
font-family: Arial, Verdana, sans-serif;
font-size: 16px;
pointer-events: auto;
position: absolute;
left: 20px;
width: 500px;
}
.vizicities-ui .vizicities-description-ui-item p {
line-height: 1.5em;
margin: 15px;
}
.vizicities-ui .vizicities-description-ui-item.closed p {
display: none;
}

18701
build/vizi.js 100644

File diff suppressed because one or more lines are too long

972
build/vizi.min.js vendored 100644

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -1,139 +0,0 @@
#ui-loading-container {
display: flex;
display: -webkit-box;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
align-items: center;
-webkit-box-align: center;
justify-content: center;
-webkit-box-pack: center;
opacity: 1;
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
#ui-loading-container.inactive {
opacity: 0;
}
.ui-loading-timer-container {
position: relative;
}
.ui-loading-timer {
width: 5em;
height: 5em;
display: flex;
align-items: center;
justify-content: center;
display: -webkit-box;
-webkit-box-align: center;
-webkit-box-pack: center;
border: .5em solid #f5f5f5;
border-radius: 100%;
position: relative;
}
.ui-loading-timer:before, .ui-loading-timer:after {
content: '';
display: block;
position: absolute;
}
.ui-loading-timer:before {
height: .5em;
width: .5em;
top: -1.48em;
border-radius: 100%;
left: 50%;
margin-left: -0.75em;
background: #666666;
border: .5em solid #f5f5f5;
}
.ui-loading-timer:after {
width: 1em;
height: 1em;
background: #f5f5f5;
right: 0;
top: -0.25em;
border-radius: 100%;
}
.ui-loading-hand {
background: #666666;
height: 1em;
width: 1em;
position: relative;
display: flex;
display: -webkit-box;
justify-content: center;
-webkit-box-pack: center;
border-radius: 100%;
border: 1.3em solid #f5f5f5;
}
.ui-loading-hand:before, .ui-loading-hand:after {
content: '';
display: block;
position: relative;
}
.ui-loading-hand:before {
width: .325em;
height: 1.5em;
top: -1.35em;
background: #666666;
-webkit-animation: countdown 5s linear infinite;
-webkit-transform-origin: 50% 125%;
-moz-animation: countdown 5s linear infinite;
-moz-transform-origin: 50% 125%;
}
@-webkit-keyframes countdown {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@-moz-keyframes countdown {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
}
}
.ui-loading-indicator-container {
position: relative;
width: 250px;
height: 50px;
margin: 40px 0 0;
background: rgba(0, 0, 0, 0.1);
pointer-events: none;
overflow: hidden;
}
.ui-loading-indicator-bar {
position: absolute;
height: 100%;
width: 100%;
background: #f5f5f5;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
-webkit-transition: -webkit-transform 0.5s linear;
transition: transform 0.5s linear;
}

Wyświetl plik

@ -1,11 +0,0 @@
/* Extending defaults from Attribution.js and OSMEdit.js */
.ui-attribution a, .ui-osm-edit a,
.ui-attribution a:visited, .ui-osm-edit a:visited {
color: #222;
text-decoration: none;
}
.ui-attribution a:hover, .ui-osm-edit a:hover {
color: #222;
text-decoration: underline;
}

Wyświetl plik

@ -0,0 +1,151 @@
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"bbox": [ -0.08018118, 51.48451552, 0.00992548, 51.54459039 ],
"features": [
{ "type": "Feature", "properties": { "FID": 0, "LSOA11CD": "E01033712", "LSOA11NM": "Hackney 023G", "MSOA11CD": "E02000367", "MSOA11NM": "Hackney 023", "LAD11CD": "E09000012", "LAD11NM": "Hackney", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1578, "HHOLDRES": 1578, "COMESTRES": 0, "POPDEN": 97.200000, "HHOLDS": 661, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.05983083, 51.53027893, -0.05041445, 51.53506602 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05151024, 51.53047702 ], [ -0.05219541, 51.53027893 ], [ -0.05221875, 51.53039523 ], [ -0.05191007, 51.53073928 ], [ -0.05244453, 51.53084601 ], [ -0.05241563, 51.53113699 ], [ -0.0528115, 51.53146688 ], [ -0.05277988, 51.53164416 ], [ -0.05327788, 51.53181709 ], [ -0.05349735, 51.53202552 ], [ -0.05426334, 51.53195668 ], [ -0.05425862, 51.53238853 ], [ -0.05599984, 51.5321071 ], [ -0.05609546, 51.53185779 ], [ -0.05592901, 51.53166416 ], [ -0.05573628, 51.53109079 ], [ -0.05592955, 51.5309169 ], [ -0.05649791, 51.53091503 ], [ -0.05663974, 51.53119698 ], [ -0.05726387, 51.5310994 ], [ -0.05741433, 51.53129074 ], [ -0.05772455, 51.53217805 ], [ -0.05804818, 51.53191873 ], [ -0.05833419, 51.53186745 ], [ -0.05842258, 51.53174871 ], [ -0.05973885, 51.53196627 ], [ -0.05983083, 51.53210412 ], [ -0.05967081, 51.53213745 ], [ -0.05964838, 51.53232592 ], [ -0.05930437, 51.53261699 ], [ -0.05908162, 51.53310791 ], [ -0.05884153, 51.53332875 ], [ -0.0588854, 51.53365322 ], [ -0.05872946, 51.53392941 ], [ -0.0588307, 51.53405055 ], [ -0.05809296, 51.53414707 ], [ -0.05727864, 51.53437314 ], [ -0.05619033, 51.53476513 ], [ -0.05522738, 51.53503006 ], [ -0.05425253, 51.53506602 ], [ -0.05333005, 51.53497315 ], [ -0.05281954, 51.53483512 ], [ -0.05253844, 51.53474902 ], [ -0.05218972, 51.53310157 ], [ -0.05389875, 51.5329231 ], [ -0.05041445, 51.53185008 ], [ -0.05091315, 51.53103486 ], [ -0.05123122, 51.53081218 ], [ -0.05151024, 51.53047702 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 1, "LSOA11CD": "E01004266", "LSOA11NM": "Tower Hamlets 007D", "MSOA11CD": "E02000870", "MSOA11NM": "Tower Hamlets 007", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1545, "HHOLDRES": 1545, "COMESTRES": 0, "POPDEN": 188.200000, "HHOLDS": 583, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.05810323, 51.52792836, -0.05191007, 51.53238853 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05219541, 51.53027893 ], [ -0.05383392, 51.52984449 ], [ -0.05583716, 51.52926457 ], [ -0.05580286, 51.5291731 ], [ -0.05592235, 51.52942251 ], [ -0.05678125, 51.52928914 ], [ -0.05671797, 51.52917433 ], [ -0.05615152, 51.52885592 ], [ -0.05643166, 51.52865528 ], [ -0.05660068, 51.52827089 ], [ -0.05689009, 51.5281109 ], [ -0.0569303, 51.52796824 ], [ -0.05779647, 51.52792836 ], [ -0.0578325, 51.52796608 ], [ -0.05810323, 51.52933274 ], [ -0.05740668, 51.52943811 ], [ -0.0576487, 51.53007415 ], [ -0.05758446, 51.53017089 ], [ -0.05693774, 51.5301364 ], [ -0.05700097, 51.53050153 ], [ -0.05726387, 51.5310994 ], [ -0.05663974, 51.53119698 ], [ -0.05649791, 51.53091503 ], [ -0.05592955, 51.5309169 ], [ -0.05573628, 51.53109079 ], [ -0.05592901, 51.53166416 ], [ -0.05609546, 51.53185779 ], [ -0.05599984, 51.5321071 ], [ -0.05425862, 51.53238853 ], [ -0.05426334, 51.53195668 ], [ -0.05349735, 51.53202552 ], [ -0.05327788, 51.53181709 ], [ -0.05277988, 51.53164416 ], [ -0.0528115, 51.53146688 ], [ -0.05241563, 51.53113699 ], [ -0.05244453, 51.53084601 ], [ -0.05191007, 51.53073928 ], [ -0.05221875, 51.53039523 ], [ -0.05219541, 51.53027893 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 2, "LSOA11CD": "E01004200", "LSOA11NM": "Tower Hamlets 005A", "MSOA11CD": "E02000868", "MSOA11NM": "Tower Hamlets 005", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1566, "HHOLDRES": 1394, "COMESTRES": 172, "POPDEN": 273.300000, "HHOLDS": 585, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.06049432, 51.52721876, -0.05693774, 51.53217805 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05726387, 51.5310994 ], [ -0.05700097, 51.53050153 ], [ -0.05693774, 51.5301364 ], [ -0.05758446, 51.53017089 ], [ -0.0576487, 51.53007415 ], [ -0.05740668, 51.52943811 ], [ -0.05810323, 51.52933274 ], [ -0.0578325, 51.52796608 ], [ -0.05779647, 51.52792836 ], [ -0.0577481, 51.52744145 ], [ -0.05833066, 51.52738554 ], [ -0.0583577, 51.52746975 ], [ -0.05888809, 51.52741422 ], [ -0.05902976, 51.52721876 ], [ -0.05934164, 51.52744831 ], [ -0.05925696, 51.52775852 ], [ -0.05840436, 51.52781494 ], [ -0.05847895, 51.5282958 ], [ -0.05882387, 51.52831951 ], [ -0.05896562, 51.52871752 ], [ -0.05929281, 51.52983804 ], [ -0.05989307, 51.52962315 ], [ -0.06002952, 51.52980526 ], [ -0.060416, 51.53054906 ], [ -0.06031819, 51.53062281 ], [ -0.06049432, 51.53100045 ], [ -0.06014201, 51.53116195 ], [ -0.06032701, 51.5313676 ], [ -0.06035862, 51.53171776 ], [ -0.06003664, 51.53176629 ], [ -0.05958798, 51.53169012 ], [ -0.05973885, 51.53196627 ], [ -0.05842258, 51.53174871 ], [ -0.05833419, 51.53186745 ], [ -0.05804818, 51.53191873 ], [ -0.05772455, 51.53217805 ], [ -0.05741433, 51.53129074 ], [ -0.05726387, 51.5310994 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 3, "LSOA11CD": "E01004200", "LSOA11NM": "Tower Hamlets 005A", "MSOA11CD": "E02000868", "MSOA11NM": "Tower Hamlets 005", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1566, "HHOLDRES": 1394, "COMESTRES": 172, "POPDEN": 273.300000, "HHOLDS": 585, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.06408954, 51.52919481, -0.05958798, 51.53210412 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05983083, 51.53210412 ], [ -0.05973885, 51.53196627 ], [ -0.05958798, 51.53169012 ], [ -0.06003664, 51.53176629 ], [ -0.06035862, 51.53171776 ], [ -0.06032701, 51.5313676 ], [ -0.06014201, 51.53116195 ], [ -0.06049432, 51.53100045 ], [ -0.06031819, 51.53062281 ], [ -0.060416, 51.53054906 ], [ -0.06002952, 51.52980526 ], [ -0.05989307, 51.52962315 ], [ -0.06127494, 51.52919481 ], [ -0.06155332, 51.52979255 ], [ -0.06264835, 51.52958776 ], [ -0.06262278, 51.5295109 ], [ -0.06301065, 51.53022324 ], [ -0.06347759, 51.53010836 ], [ -0.06365334, 51.5301529 ], [ -0.0638405, 51.53071355 ], [ -0.06397093, 51.53069772 ], [ -0.06408954, 51.53096047 ], [ -0.06388834, 51.53102443 ], [ -0.06408695, 51.53140597 ], [ -0.06317183, 51.53152086 ], [ -0.06195201, 51.53172552 ], [ -0.05983083, 51.53210412 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 4, "LSOA11CD": "E01004201", "LSOA11NM": "Tower Hamlets 002D", "MSOA11CD": "E02000865", "MSOA11NM": "Tower Hamlets 002", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1556, "HHOLDRES": 1533, "COMESTRES": 23, "POPDEN": 119.900000, "HHOLDS": 619, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.05389875, 51.53047702, -0.04448662, 51.53474902 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04448662, 51.53179564 ], [ -0.04475126, 51.53161258 ], [ -0.04536604, 51.53138733 ], [ -0.04652046, 51.53112259 ], [ -0.0478985, 51.53100118 ], [ -0.04975042, 51.53075748 ], [ -0.05038601, 51.53072954 ], [ -0.05088991, 51.5306561 ], [ -0.05151024, 51.53047702 ], [ -0.05123122, 51.53081218 ], [ -0.05091315, 51.53103486 ], [ -0.05041445, 51.53185008 ], [ -0.05389875, 51.5329231 ], [ -0.05218972, 51.53310157 ], [ -0.05253844, 51.53474902 ], [ -0.04647939, 51.53273442 ], [ -0.0455975, 51.53236845 ], [ -0.04448662, 51.53179564 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 5, "LSOA11CD": "E01033712", "LSOA11NM": "Hackney 023G", "MSOA11CD": "E02000367", "MSOA11NM": "Hackney 023", "LAD11CD": "E09000012", "LAD11NM": "Hackney", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1578, "HHOLDRES": 1578, "COMESTRES": 0, "POPDEN": 97.200000, "HHOLDS": 661, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.066061, 51.53126505, -0.05872946, 51.53546292 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0588307, 51.53405055 ], [ -0.05872946, 51.53392941 ], [ -0.0588854, 51.53365322 ], [ -0.05884153, 51.53332875 ], [ -0.05908162, 51.53310791 ], [ -0.05930437, 51.53261699 ], [ -0.05964838, 51.53232592 ], [ -0.05967081, 51.53213745 ], [ -0.05983083, 51.53210412 ], [ -0.06195201, 51.53172552 ], [ -0.06317183, 51.53152086 ], [ -0.06408695, 51.53140597 ], [ -0.0653419, 51.53126505 ], [ -0.06554726, 51.53127344 ], [ -0.06561119, 51.53144057 ], [ -0.066061, 51.53162756 ], [ -0.06534353, 51.53288215 ], [ -0.06512014, 51.53316337 ], [ -0.06495968, 51.53284712 ], [ -0.06324224, 51.53302508 ], [ -0.06221724, 51.53319388 ], [ -0.06269699, 51.53404503 ], [ -0.06281746, 51.53458209 ], [ -0.0628294, 51.53493792 ], [ -0.06244938, 51.53546292 ], [ -0.06207421, 51.53540389 ], [ -0.06168225, 51.53523302 ], [ -0.06132066, 51.5349619 ], [ -0.06066352, 51.53439306 ], [ -0.06043877, 51.53427412 ], [ -0.05988825, 51.53410202 ], [ -0.05933665, 51.53404006 ], [ -0.0588307, 51.53405055 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 6, "LSOA11CD": "E01004200", "LSOA11NM": "Tower Hamlets 005A", "MSOA11CD": "E02000868", "MSOA11NM": "Tower Hamlets 005", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1566, "HHOLDRES": 1394, "COMESTRES": 172, "POPDEN": 273.300000, "HHOLDS": 585, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.06479401, 51.5264028, -0.05537408, 51.52983804 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05779647, 51.52792836 ], [ -0.0569303, 51.52796824 ], [ -0.05689009, 51.5281109 ], [ -0.05660068, 51.52827089 ], [ -0.05643166, 51.52865528 ], [ -0.05615152, 51.52885592 ], [ -0.05671797, 51.52917433 ], [ -0.05678125, 51.52928914 ], [ -0.05592235, 51.52942251 ], [ -0.05580286, 51.5291731 ], [ -0.05556775, 51.52843964 ], [ -0.05550651, 51.5278468 ], [ -0.05537408, 51.52748672 ], [ -0.05571879, 51.52744024 ], [ -0.05803247, 51.52714183 ], [ -0.05951848, 51.52696774 ], [ -0.06461538, 51.5264028 ], [ -0.06479401, 51.5269804 ], [ -0.06373598, 51.52706078 ], [ -0.06376353, 51.5272238 ], [ -0.06346473, 51.5272483 ], [ -0.06336683, 51.52709794 ], [ -0.06296861, 51.52713802 ], [ -0.06307271, 51.52774226 ], [ -0.06269584, 51.52778999 ], [ -0.06261627, 51.5276268 ], [ -0.06213855, 51.52767287 ], [ -0.06217376, 51.52809473 ], [ -0.06151719, 51.52840522 ], [ -0.06147976, 51.52852853 ], [ -0.06204081, 51.52895427 ], [ -0.0623154, 51.5288687 ], [ -0.06262278, 51.5295109 ], [ -0.06264835, 51.52958776 ], [ -0.06155332, 51.52979255 ], [ -0.06127494, 51.52919481 ], [ -0.05989307, 51.52962315 ], [ -0.05929281, 51.52983804 ], [ -0.05896562, 51.52871752 ], [ -0.05882387, 51.52831951 ], [ -0.05847895, 51.5282958 ], [ -0.05840436, 51.52781494 ], [ -0.05925696, 51.52775852 ], [ -0.05934164, 51.52744831 ], [ -0.05902976, 51.52721876 ], [ -0.05888809, 51.52741422 ], [ -0.0583577, 51.52746975 ], [ -0.05833066, 51.52738554 ], [ -0.0577481, 51.52744145 ], [ -0.05779647, 51.52792836 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 7, "LSOA11CD": "E01004200", "LSOA11NM": "Tower Hamlets 005A", "MSOA11CD": "E02000868", "MSOA11NM": "Tower Hamlets 005", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1566, "HHOLDRES": 1394, "COMESTRES": 172, "POPDEN": 273.300000, "HHOLDS": 585, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.06629206, 51.5269804, -0.06147976, 51.53162756 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06408695, 51.53140597 ], [ -0.06388834, 51.53102443 ], [ -0.06408954, 51.53096047 ], [ -0.06397093, 51.53069772 ], [ -0.0638405, 51.53071355 ], [ -0.06365334, 51.5301529 ], [ -0.06347759, 51.53010836 ], [ -0.06301065, 51.53022324 ], [ -0.06262278, 51.5295109 ], [ -0.0623154, 51.5288687 ], [ -0.06204081, 51.52895427 ], [ -0.06147976, 51.52852853 ], [ -0.06151719, 51.52840522 ], [ -0.06217376, 51.52809473 ], [ -0.06213855, 51.52767287 ], [ -0.06261627, 51.5276268 ], [ -0.06269584, 51.52778999 ], [ -0.06307271, 51.52774226 ], [ -0.06296861, 51.52713802 ], [ -0.06336683, 51.52709794 ], [ -0.06346473, 51.5272483 ], [ -0.06376353, 51.5272238 ], [ -0.06373598, 51.52706078 ], [ -0.06479401, 51.5269804 ], [ -0.06519131, 51.52822659 ], [ -0.06499256, 51.52830505 ], [ -0.06542982, 51.52955049 ], [ -0.06542472, 51.52977733 ], [ -0.06591045, 51.53101505 ], [ -0.06598509, 51.53120434 ], [ -0.06629206, 51.53117348 ], [ -0.066061, 51.53162756 ], [ -0.06561119, 51.53144057 ], [ -0.06554726, 51.53127344 ], [ -0.0653419, 51.53126505 ], [ -0.06408695, 51.53140597 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 8, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.06436593, 51.51907458, -0.05803854, 51.52416425 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05810438, 51.5219535 ], [ -0.05803854, 51.52170579 ], [ -0.05951817, 51.52148748 ], [ -0.05901423, 51.52079569 ], [ -0.05873913, 51.52048538 ], [ -0.06044549, 51.52001901 ], [ -0.06151341, 51.51964998 ], [ -0.06177993, 51.51948351 ], [ -0.0624536, 51.51923387 ], [ -0.06312106, 51.51907458 ], [ -0.06336881, 51.51958327 ], [ -0.06358474, 51.51990936 ], [ -0.06385088, 51.5204024 ], [ -0.06428795, 51.52148327 ], [ -0.06436593, 51.52174717 ], [ -0.06423226, 51.52262611 ], [ -0.06407867, 51.5231928 ], [ -0.06393923, 51.52373984 ], [ -0.06329854, 51.52378018 ], [ -0.06367715, 51.52267133 ], [ -0.06371783, 51.52244491 ], [ -0.06329897, 51.52224906 ], [ -0.06324791, 51.52197673 ], [ -0.06274569, 51.52196844 ], [ -0.06232169, 51.5220798 ], [ -0.0623707, 51.52260515 ], [ -0.06207357, 51.52269575 ], [ -0.06208456, 51.52312658 ], [ -0.06139949, 51.52302052 ], [ -0.061166, 51.52313158 ], [ -0.06033714, 51.52309503 ], [ -0.06038695, 51.52410976 ], [ -0.05933227, 51.52416425 ], [ -0.05924454, 51.52351532 ], [ -0.05861705, 51.52356588 ], [ -0.05889912, 51.52327407 ], [ -0.05865679, 51.52287455 ], [ -0.05924302, 51.5224177 ], [ -0.05913313, 51.52232559 ], [ -0.0591392, 51.5220314 ], [ -0.05875081, 51.52186457 ], [ -0.05810438, 51.5219535 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 9, "LSOA11CD": "E01004211", "LSOA11NM": "Tower Hamlets 013D", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1463, "HHOLDRES": 1461, "COMESTRES": 2, "POPDEN": 88.800000, "HHOLDS": 720, "AVHHOLDSZ": 2.000000 }, "bbox": [ -0.05933227, 51.52080835, -0.05304669, 51.52455618 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05857162, 51.52455618 ], [ -0.05845352, 51.52414971 ], [ -0.05787193, 51.52426598 ], [ -0.05737257, 51.52448253 ], [ -0.05649381, 51.52446797 ], [ -0.05654586, 51.52324581 ], [ -0.05712861, 51.52325986 ], [ -0.05727581, 51.52305965 ], [ -0.0576218, 51.52294501 ], [ -0.05814357, 51.5226248 ], [ -0.05652713, 51.52266996 ], [ -0.05651435, 51.52282022 ], [ -0.05599982, 51.52274339 ], [ -0.05550275, 51.52281165 ], [ -0.05512591, 51.52262852 ], [ -0.05509707, 51.52237917 ], [ -0.05482778, 51.52220567 ], [ -0.05410988, 51.52222521 ], [ -0.05385886, 51.52236492 ], [ -0.05360229, 51.52211343 ], [ -0.05379294, 51.52191188 ], [ -0.05320983, 51.52177743 ], [ -0.05304669, 51.52144073 ], [ -0.05382801, 51.5212116 ], [ -0.05379054, 51.52108837 ], [ -0.05432133, 51.5210652 ], [ -0.05439533, 51.52093315 ], [ -0.0548277, 51.52100165 ], [ -0.0554263, 51.52088405 ], [ -0.05549258, 51.52080835 ], [ -0.05605709, 51.5209893 ], [ -0.055741, 51.5215134 ], [ -0.05605979, 51.52163659 ], [ -0.05681764, 51.52142801 ], [ -0.05678107, 51.52169345 ], [ -0.05749327, 51.52174852 ], [ -0.05743406, 51.52199857 ], [ -0.05812218, 51.52211185 ], [ -0.05810438, 51.5219535 ], [ -0.05875081, 51.52186457 ], [ -0.0591392, 51.5220314 ], [ -0.05913313, 51.52232559 ], [ -0.05924302, 51.5224177 ], [ -0.05865679, 51.52287455 ], [ -0.05889912, 51.52327407 ], [ -0.05861705, 51.52356588 ], [ -0.05924454, 51.52351532 ], [ -0.05933227, 51.52416425 ], [ -0.05899709, 51.52415871 ], [ -0.05896544, 51.52435545 ], [ -0.05857162, 51.52455618 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 10, "LSOA11CD": "E01004208", "LSOA11NM": "Tower Hamlets 013C", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1976, "HHOLDRES": 1842, "COMESTRES": 134, "POPDEN": 122.100000, "HHOLDS": 788, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05331997, 51.52125149, -0.046207, 51.52483127 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04712187, 51.52274479 ], [ -0.046207, 51.52181744 ], [ -0.0490225, 51.52125149 ], [ -0.04919441, 51.52239105 ], [ -0.05002882, 51.52232433 ], [ -0.05006413, 51.5227084 ], [ -0.05080517, 51.52264694 ], [ -0.05061114, 51.52240409 ], [ -0.05111284, 51.52244043 ], [ -0.05146173, 51.5227499 ], [ -0.05184466, 51.52263062 ], [ -0.05251574, 51.52227329 ], [ -0.05298116, 51.52225397 ], [ -0.05331997, 51.52252664 ], [ -0.05279378, 51.52269543 ], [ -0.05292285, 51.52276734 ], [ -0.05218194, 51.5228137 ], [ -0.05156088, 51.52304387 ], [ -0.05152956, 51.52319237 ], [ -0.05114187, 51.52326587 ], [ -0.0507682, 51.52356405 ], [ -0.04986935, 51.52384927 ], [ -0.04982272, 51.52380938 ], [ -0.0490303, 51.52407602 ], [ -0.04929657, 51.52424339 ], [ -0.04944133, 51.52446351 ], [ -0.04892247, 51.52483127 ], [ -0.04867538, 51.52458319 ], [ -0.04792224, 51.52365424 ], [ -0.04712187, 51.52274479 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 11, "LSOA11CD": "E01004205", "LSOA11NM": "Tower Hamlets 013A", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2106, "HHOLDRES": 2106, "COMESTRES": 0, "POPDEN": 155.900000, "HHOLDS": 688, "AVHHOLDSZ": 3.100000 }, "bbox": [ -0.06312106, 51.5183705, -0.0490225, 51.52282105 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05292285, 51.52276734 ], [ -0.05279378, 51.52269543 ], [ -0.05331997, 51.52252664 ], [ -0.05298116, 51.52225397 ], [ -0.05251574, 51.52227329 ], [ -0.05184466, 51.52263062 ], [ -0.05146173, 51.5227499 ], [ -0.05111284, 51.52244043 ], [ -0.05061114, 51.52240409 ], [ -0.05080517, 51.52264694 ], [ -0.05006413, 51.5227084 ], [ -0.05002882, 51.52232433 ], [ -0.04919441, 51.52239105 ], [ -0.0490225, 51.52125149 ], [ -0.05095189, 51.52082217 ], [ -0.05296427, 51.52039948 ], [ -0.05421828, 51.52014757 ], [ -0.05634912, 51.5197805 ], [ -0.05800544, 51.51943457 ], [ -0.06179993, 51.51858851 ], [ -0.06273078, 51.5183705 ], [ -0.06312106, 51.51907458 ], [ -0.0624536, 51.51923387 ], [ -0.06177993, 51.51948351 ], [ -0.06151341, 51.51964998 ], [ -0.06044549, 51.52001901 ], [ -0.05873913, 51.52048538 ], [ -0.05901423, 51.52079569 ], [ -0.05951817, 51.52148748 ], [ -0.05803854, 51.52170579 ], [ -0.05810438, 51.5219535 ], [ -0.05812218, 51.52211185 ], [ -0.05743406, 51.52199857 ], [ -0.05749327, 51.52174852 ], [ -0.05678107, 51.52169345 ], [ -0.05681764, 51.52142801 ], [ -0.05605979, 51.52163659 ], [ -0.055741, 51.5215134 ], [ -0.05605709, 51.5209893 ], [ -0.05549258, 51.52080835 ], [ -0.0554263, 51.52088405 ], [ -0.0548277, 51.52100165 ], [ -0.05439533, 51.52093315 ], [ -0.05432133, 51.5210652 ], [ -0.05379054, 51.52108837 ], [ -0.05382801, 51.5212116 ], [ -0.05304669, 51.52144073 ], [ -0.05320983, 51.52177743 ], [ -0.05379294, 51.52191188 ], [ -0.05360229, 51.52211343 ], [ -0.05385886, 51.52236492 ], [ -0.05426867, 51.52264378 ], [ -0.05431716, 51.52274348 ], [ -0.05297584, 51.52282105 ], [ -0.05292285, 51.52276734 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 12, "LSOA11CD": "E01004208", "LSOA11NM": "Tower Hamlets 013C", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1976, "HHOLDRES": 1842, "COMESTRES": 134, "POPDEN": 122.100000, "HHOLDS": 788, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05553283, 51.52220567, -0.05178445, 51.52752421 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0533304, 51.52752421 ], [ -0.0531744, 51.52727249 ], [ -0.05299289, 51.52667562 ], [ -0.05261605, 51.52663696 ], [ -0.05267081, 51.52682937 ], [ -0.05178445, 51.52695412 ], [ -0.05179559, 51.52662994 ], [ -0.05201362, 51.52644952 ], [ -0.05193733, 51.5262795 ], [ -0.05249314, 51.52599332 ], [ -0.05292199, 51.52506519 ], [ -0.05321388, 51.52430565 ], [ -0.05307095, 51.52310622 ], [ -0.05398705, 51.52307748 ], [ -0.05399817, 51.52343263 ], [ -0.05451012, 51.52366431 ], [ -0.05450119, 51.52280743 ], [ -0.05431716, 51.52274348 ], [ -0.05426867, 51.52264378 ], [ -0.05385886, 51.52236492 ], [ -0.05410988, 51.52222521 ], [ -0.05482778, 51.52220567 ], [ -0.05509707, 51.52237917 ], [ -0.05512591, 51.52262852 ], [ -0.05494125, 51.52301238 ], [ -0.05487883, 51.52447716 ], [ -0.05490749, 51.52481936 ], [ -0.05533909, 51.52619342 ], [ -0.05553283, 51.52705994 ], [ -0.05529357, 51.52726517 ], [ -0.0533304, 51.52752421 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 13, "LSOA11CD": "E01004313", "LSOA11NM": "Tower Hamlets 009B", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2043, "HHOLDRES": 2043, "COMESTRES": 0, "POPDEN": 248.800000, "HHOLDS": 812, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.06461538, 51.52196844, -0.05571879, 51.52744024 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05857162, 51.52455618 ], [ -0.05896544, 51.52435545 ], [ -0.05899709, 51.52415871 ], [ -0.05933227, 51.52416425 ], [ -0.06038695, 51.52410976 ], [ -0.06033714, 51.52309503 ], [ -0.061166, 51.52313158 ], [ -0.06139949, 51.52302052 ], [ -0.06208456, 51.52312658 ], [ -0.06207357, 51.52269575 ], [ -0.0623707, 51.52260515 ], [ -0.06232169, 51.5220798 ], [ -0.06274569, 51.52196844 ], [ -0.06324791, 51.52197673 ], [ -0.06329897, 51.52224906 ], [ -0.06371783, 51.52244491 ], [ -0.06367715, 51.52267133 ], [ -0.06329854, 51.52378018 ], [ -0.06393923, 51.52373984 ], [ -0.06399817, 51.52427902 ], [ -0.06461538, 51.5264028 ], [ -0.05951848, 51.52696774 ], [ -0.05803247, 51.52714183 ], [ -0.05571879, 51.52744024 ], [ -0.05635601, 51.52692922 ], [ -0.0569163, 51.52709956 ], [ -0.05703572, 51.526895 ], [ -0.05692692, 51.5265207 ], [ -0.05777358, 51.52641973 ], [ -0.05786266, 51.52618431 ], [ -0.0583581, 51.52613098 ], [ -0.0582408, 51.52572625 ], [ -0.05885717, 51.52550531 ], [ -0.05857162, 51.52455618 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 14, "LSOA11CD": "E01004211", "LSOA11NM": "Tower Hamlets 013D", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1463, "HHOLDRES": 1461, "COMESTRES": 2, "POPDEN": 88.800000, "HHOLDS": 720, "AVHHOLDSZ": 2.000000 }, "bbox": [ -0.05885717, 51.5226248, -0.05487883, 51.52748672 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05512591, 51.52262852 ], [ -0.05550275, 51.52281165 ], [ -0.05599982, 51.52274339 ], [ -0.05651435, 51.52282022 ], [ -0.05652713, 51.52266996 ], [ -0.05814357, 51.5226248 ], [ -0.0576218, 51.52294501 ], [ -0.05727581, 51.52305965 ], [ -0.05712861, 51.52325986 ], [ -0.05654586, 51.52324581 ], [ -0.05649381, 51.52446797 ], [ -0.05737257, 51.52448253 ], [ -0.05787193, 51.52426598 ], [ -0.05845352, 51.52414971 ], [ -0.05857162, 51.52455618 ], [ -0.05885717, 51.52550531 ], [ -0.0582408, 51.52572625 ], [ -0.0583581, 51.52613098 ], [ -0.05786266, 51.52618431 ], [ -0.05777358, 51.52641973 ], [ -0.05692692, 51.5265207 ], [ -0.05703572, 51.526895 ], [ -0.0569163, 51.52709956 ], [ -0.05635601, 51.52692922 ], [ -0.05571879, 51.52744024 ], [ -0.05537408, 51.52748672 ], [ -0.05529357, 51.52726517 ], [ -0.05553283, 51.52705994 ], [ -0.05533909, 51.52619342 ], [ -0.05490749, 51.52481936 ], [ -0.05487883, 51.52447716 ], [ -0.05494125, 51.52301238 ], [ -0.05512591, 51.52262852 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 15, "LSOA11CD": "E01001667", "LSOA11NM": "Greenwich 036B", "MSOA11CD": "E02006929", "MSOA11NM": "Greenwich 036", "LAD11CD": "E09000011", "LAD11NM": "Greenwich", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1564, "HHOLDRES": 1564, "COMESTRES": 0, "POPDEN": 11.500000, "HHOLDS": 707, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.00961777, 51.49489345, -0.0030981, 51.49872065 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0030981, 51.49616476 ], [ -0.00411676, 51.49581766 ], [ -0.00649665, 51.49534163 ], [ -0.00655613, 51.49542817 ], [ -0.00693434, 51.49534467 ], [ -0.00710788, 51.49532964 ], [ -0.00881759, 51.49489345 ], [ -0.00907563, 51.49559785 ], [ -0.00841733, 51.49570073 ], [ -0.00798574, 51.49598771 ], [ -0.00815359, 51.49623202 ], [ -0.00864534, 51.49608418 ], [ -0.00914345, 51.49678299 ], [ -0.00947237, 51.49677174 ], [ -0.00961777, 51.49724279 ], [ -0.00960838, 51.49745846 ], [ -0.00944034, 51.49866964 ], [ -0.00860764, 51.49860154 ], [ -0.00850314, 51.49802423 ], [ -0.00689786, 51.49832628 ], [ -0.00450369, 51.49872065 ], [ -0.00430929, 51.49821624 ], [ -0.00398495, 51.49756042 ], [ -0.0036382, 51.49706736 ], [ -0.0030981, 51.49616476 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 16, "LSOA11CD": "E01032780", "LSOA11NM": "Tower Hamlets 028I", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1333, "HHOLDRES": 1333, "COMESTRES": 0, "POPDEN": 37.800000, "HHOLDS": 647, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.01733417, 51.49326366, -0.00693434, 51.50011224 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01339919, 51.4997711 ], [ -0.01367895, 51.49824602 ], [ -0.01313745, 51.49823179 ], [ -0.01280013, 51.49799682 ], [ -0.01249066, 51.49831867 ], [ -0.01221665, 51.49817499 ], [ -0.01148427, 51.49864334 ], [ -0.01133766, 51.49845226 ], [ -0.01227253, 51.4978184 ], [ -0.01200602, 51.49765201 ], [ -0.01143955, 51.49798214 ], [ -0.01092853, 51.49782382 ], [ -0.01084361, 51.49793364 ], [ -0.01026783, 51.49827797 ], [ -0.00993137, 51.49805223 ], [ -0.01012069, 51.49785346 ], [ -0.01002243, 51.49773465 ], [ -0.01017185, 51.4975737 ], [ -0.00960838, 51.49745846 ], [ -0.00961777, 51.49724279 ], [ -0.00947237, 51.49677174 ], [ -0.00914345, 51.49678299 ], [ -0.00864534, 51.49608418 ], [ -0.00815359, 51.49623202 ], [ -0.00798574, 51.49598771 ], [ -0.00841733, 51.49570073 ], [ -0.00907563, 51.49559785 ], [ -0.00881759, 51.49489345 ], [ -0.00710788, 51.49532964 ], [ -0.00693434, 51.49534467 ], [ -0.00719933, 51.49517427 ], [ -0.00734854, 51.49485917 ], [ -0.00804244, 51.49492158 ], [ -0.00776297, 51.49451342 ], [ -0.00721614, 51.49383866 ], [ -0.00722472, 51.49368192 ], [ -0.00696061, 51.49336801 ], [ -0.00732624, 51.49326366 ], [ -0.00821209, 51.49412537 ], [ -0.0085904, 51.4944967 ], [ -0.00911731, 51.49439058 ], [ -0.0093131, 51.49447274 ], [ -0.00962612, 51.495085 ], [ -0.0101851, 51.49480072 ], [ -0.01103043, 51.49463969 ], [ -0.01302654, 51.49387872 ], [ -0.01329264, 51.49374508 ], [ -0.01353399, 51.49404041 ], [ -0.01400503, 51.49447505 ], [ -0.01429024, 51.49448926 ], [ -0.01448382, 51.4933494 ], [ -0.01519825, 51.49336848 ], [ -0.01733417, 51.4934605 ], [ -0.01728093, 51.49384959 ], [ -0.01695966, 51.49619727 ], [ -0.01669618, 51.49847117 ], [ -0.0165291, 51.49991291 ], [ -0.01621238, 51.49988589 ], [ -0.0161664, 51.50011224 ], [ -0.01458662, 51.49993496 ], [ -0.01339919, 51.4997711 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 17, "LSOA11CD": "E01001667", "LSOA11NM": "Greenwich 036B", "MSOA11CD": "E02006929", "MSOA11NM": "Greenwich 036", "LAD11CD": "E09000011", "LAD11NM": "Greenwich", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1564, "HHOLDRES": 1564, "COMESTRES": 0, "POPDEN": 11.500000, "HHOLDS": 707, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.00894443, 51.49089293, -0.00119908, 51.49616476 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00119908, 51.49348269 ], [ -0.00482498, 51.49251201 ], [ -0.00495888, 51.49248387 ], [ -0.00522289, 51.4927766 ], [ -0.00614778, 51.49257048 ], [ -0.00647075, 51.49243209 ], [ -0.00566956, 51.49164508 ], [ -0.00559182, 51.49144591 ], [ -0.00586086, 51.49089293 ], [ -0.00786046, 51.49128664 ], [ -0.00801572, 51.49123443 ], [ -0.00807248, 51.49138017 ], [ -0.00832883, 51.49144747 ], [ -0.00811621, 51.49191941 ], [ -0.00790943, 51.49196217 ], [ -0.00795622, 51.49231441 ], [ -0.00761514, 51.49246731 ], [ -0.00721196, 51.49242991 ], [ -0.00707296, 51.49263008 ], [ -0.00773888, 51.49294265 ], [ -0.0083617, 51.49296107 ], [ -0.00841446, 51.49332466 ], [ -0.00862626, 51.49350836 ], [ -0.00870387, 51.4937327 ], [ -0.00894443, 51.49382695 ], [ -0.00821209, 51.49412537 ], [ -0.00732624, 51.49326366 ], [ -0.00696061, 51.49336801 ], [ -0.00722472, 51.49368192 ], [ -0.00721614, 51.49383866 ], [ -0.00776297, 51.49451342 ], [ -0.00804244, 51.49492158 ], [ -0.00734854, 51.49485917 ], [ -0.00719933, 51.49517427 ], [ -0.00693434, 51.49534467 ], [ -0.00655613, 51.49542817 ], [ -0.00649665, 51.49534163 ], [ -0.00411676, 51.49581766 ], [ -0.0030981, 51.49616476 ], [ -0.00260016, 51.49533261 ], [ -0.00219018, 51.49472154 ], [ -0.00160673, 51.49414477 ], [ -0.00119908, 51.49348269 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 18, "LSOA11CD": "E01004275", "LSOA11NM": "Tower Hamlets 031B", "MSOA11CD": "E02000894", "MSOA11NM": "Tower Hamlets 031", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 135.500000, "HHOLDS": 768, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.0156736, 51.48451552, -0.0058029, 51.495085 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00821209, 51.49412537 ], [ -0.00894443, 51.49382695 ], [ -0.00870387, 51.4937327 ], [ -0.00862626, 51.49350836 ], [ -0.00841446, 51.49332466 ], [ -0.0083617, 51.49296107 ], [ -0.00773888, 51.49294265 ], [ -0.00707296, 51.49263008 ], [ -0.00721196, 51.49242991 ], [ -0.00761514, 51.49246731 ], [ -0.00795622, 51.49231441 ], [ -0.00790943, 51.49196217 ], [ -0.00811621, 51.49191941 ], [ -0.00832883, 51.49144747 ], [ -0.00807248, 51.49138017 ], [ -0.00801572, 51.49123443 ], [ -0.00847856, 51.49032591 ], [ -0.00871798, 51.4897904 ], [ -0.00833952, 51.48972859 ], [ -0.00820815, 51.49005927 ], [ -0.00787745, 51.49047332 ], [ -0.00668479, 51.49025183 ], [ -0.00665863, 51.49010589 ], [ -0.00682335, 51.48999042 ], [ -0.0058029, 51.48979068 ], [ -0.00601415, 51.48964085 ], [ -0.00598024, 51.48933621 ], [ -0.00608179, 51.48910668 ], [ -0.00628057, 51.48895427 ], [ -0.00663694, 51.48902015 ], [ -0.00690263, 51.48880631 ], [ -0.00746215, 51.48852805 ], [ -0.00786437, 51.48838772 ], [ -0.00735272, 51.48782708 ], [ -0.00774009, 51.48737539 ], [ -0.00895217, 51.48706054 ], [ -0.0097353, 51.48693894 ], [ -0.00992426, 51.48700552 ], [ -0.01011043, 51.48659623 ], [ -0.00968158, 51.48606234 ], [ -0.00874796, 51.48504987 ], [ -0.01058633, 51.48467847 ], [ -0.01103708, 51.48462246 ], [ -0.01277645, 51.48451552 ], [ -0.0132691, 51.48629125 ], [ -0.01314189, 51.48629725 ], [ -0.01331335, 51.48714178 ], [ -0.01342279, 51.4881811 ], [ -0.0136128, 51.48878108 ], [ -0.01417132, 51.48937395 ], [ -0.01426382, 51.489338 ], [ -0.01520091, 51.49027396 ], [ -0.0156736, 51.49062593 ], [ -0.01561307, 51.49068106 ], [ -0.01543877, 51.49080884 ], [ -0.01554189, 51.49141971 ], [ -0.01534112, 51.49173078 ], [ -0.0149528, 51.49254467 ], [ -0.01478132, 51.49334157 ], [ -0.01519825, 51.49336848 ], [ -0.01448382, 51.4933494 ], [ -0.01429024, 51.49448926 ], [ -0.01400503, 51.49447505 ], [ -0.01353399, 51.49404041 ], [ -0.01329264, 51.49374508 ], [ -0.01302654, 51.49387872 ], [ -0.01103043, 51.49463969 ], [ -0.0101851, 51.49480072 ], [ -0.00962612, 51.495085 ], [ -0.0093131, 51.49447274 ], [ -0.00911731, 51.49439058 ], [ -0.0085904, 51.4944967 ], [ -0.00821209, 51.49412537 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 19, "LSOA11CD": "E01001667", "LSOA11NM": "Greenwich 036B", "MSOA11CD": "E02006929", "MSOA11NM": "Greenwich 036", "LAD11CD": "E09000011", "LAD11NM": "Greenwich", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1564, "HHOLDRES": 1564, "COMESTRES": 0, "POPDEN": 11.500000, "HHOLDS": 707, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.01011043, 51.48504987, -0.0003944, 51.49348269 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00874796, 51.48504987 ], [ -0.00968158, 51.48606234 ], [ -0.01011043, 51.48659623 ], [ -0.00992426, 51.48700552 ], [ -0.0097353, 51.48693894 ], [ -0.00895217, 51.48706054 ], [ -0.00774009, 51.48737539 ], [ -0.00735272, 51.48782708 ], [ -0.00786437, 51.48838772 ], [ -0.00746215, 51.48852805 ], [ -0.00690263, 51.48880631 ], [ -0.00663694, 51.48902015 ], [ -0.00628057, 51.48895427 ], [ -0.00608179, 51.48910668 ], [ -0.00598024, 51.48933621 ], [ -0.00601415, 51.48964085 ], [ -0.0058029, 51.48979068 ], [ -0.00682335, 51.48999042 ], [ -0.00665863, 51.49010589 ], [ -0.00668479, 51.49025183 ], [ -0.00787745, 51.49047332 ], [ -0.00820815, 51.49005927 ], [ -0.00833952, 51.48972859 ], [ -0.00871798, 51.4897904 ], [ -0.00847856, 51.49032591 ], [ -0.00801572, 51.49123443 ], [ -0.00786046, 51.49128664 ], [ -0.00586086, 51.49089293 ], [ -0.00559182, 51.49144591 ], [ -0.00566956, 51.49164508 ], [ -0.00647075, 51.49243209 ], [ -0.00614778, 51.49257048 ], [ -0.00522289, 51.4927766 ], [ -0.00495888, 51.49248387 ], [ -0.00482498, 51.49251201 ], [ -0.00119908, 51.49348269 ], [ -0.00106109, 51.49325979 ], [ -0.00078101, 51.49249989 ], [ -0.0003944, 51.49133505 ], [ -0.00049128, 51.49019108 ], [ -0.00066907, 51.48960523 ], [ -0.00118203, 51.48864315 ], [ -0.00138861, 51.48836621 ], [ -0.00202471, 51.48771636 ], [ -0.0029326, 51.48708926 ], [ -0.00453228, 51.48626737 ], [ -0.0053597, 51.48591443 ], [ -0.00657424, 51.48554038 ], [ -0.00874796, 51.48504987 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 20, "LSOA11CD": "E01004243", "LSOA11NM": "Tower Hamlets 020A", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1789, "HHOLDRES": 1789, "COMESTRES": 0, "POPDEN": 153.400000, "HHOLDS": 614, "AVHHOLDSZ": 2.900000 }, "bbox": [ -0.01315003, 51.50703428, -0.00412338, 51.5120009 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00444073, 51.51120165 ], [ -0.00412338, 51.51054876 ], [ -0.00550238, 51.5102805 ], [ -0.00543645, 51.51063713 ], [ -0.00690598, 51.51072518 ], [ -0.00693013, 51.51029974 ], [ -0.00687146, 51.50978282 ], [ -0.00767548, 51.50978198 ], [ -0.0076166, 51.5094301 ], [ -0.00762808, 51.50883678 ], [ -0.00689169, 51.50886922 ], [ -0.00686174, 51.50871902 ], [ -0.0064141, 51.50886042 ], [ -0.00543329, 51.50794513 ], [ -0.00528117, 51.50779866 ], [ -0.00582766, 51.50765735 ], [ -0.00647362, 51.50782126 ], [ -0.00705553, 51.50775689 ], [ -0.00758912, 51.50774796 ], [ -0.0074752, 51.50738632 ], [ -0.00795012, 51.50707065 ], [ -0.00845608, 51.50703428 ], [ -0.00878101, 51.50718369 ], [ -0.00928148, 51.50727311 ], [ -0.01067873, 51.50715693 ], [ -0.01093451, 51.50736467 ], [ -0.01212675, 51.50725435 ], [ -0.01205159, 51.50752934 ], [ -0.01185167, 51.50767321 ], [ -0.01174816, 51.50789923 ], [ -0.01186234, 51.50823515 ], [ -0.01235254, 51.50889206 ], [ -0.01259208, 51.50930713 ], [ -0.01290998, 51.51013593 ], [ -0.01315003, 51.51113989 ], [ -0.01105226, 51.51122095 ], [ -0.0079982, 51.51141894 ], [ -0.00773787, 51.51142242 ], [ -0.00691201, 51.51149898 ], [ -0.00575649, 51.51170192 ], [ -0.00429845, 51.5120009 ], [ -0.0046523, 51.5116369 ], [ -0.00444073, 51.51120165 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 21, "LSOA11CD": "E01032779", "LSOA11NM": "Tower Hamlets 028H", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1089, "HHOLDRES": 1089, "COMESTRES": 0, "POPDEN": 365.400000, "HHOLDS": 565, "AVHHOLDSZ": 1.900000 }, "bbox": [ -0.01367895, 51.49745846, -0.00396095, 51.50505892 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00396095, 51.50350024 ], [ -0.00423551, 51.50311989 ], [ -0.00458838, 51.50252577 ], [ -0.00483001, 51.50190094 ], [ -0.00508639, 51.50143304 ], [ -0.00516756, 51.50091494 ], [ -0.00507747, 51.50073004 ], [ -0.00458353, 51.49894707 ], [ -0.00450369, 51.49872065 ], [ -0.00689786, 51.49832628 ], [ -0.00850314, 51.49802423 ], [ -0.00860764, 51.49860154 ], [ -0.00944034, 51.49866964 ], [ -0.00960838, 51.49745846 ], [ -0.01017185, 51.4975737 ], [ -0.01002243, 51.49773465 ], [ -0.01012069, 51.49785346 ], [ -0.00993137, 51.49805223 ], [ -0.01026783, 51.49827797 ], [ -0.01084361, 51.49793364 ], [ -0.01092853, 51.49782382 ], [ -0.01143955, 51.49798214 ], [ -0.01200602, 51.49765201 ], [ -0.01227253, 51.4978184 ], [ -0.01133766, 51.49845226 ], [ -0.01148427, 51.49864334 ], [ -0.01221665, 51.49817499 ], [ -0.01249066, 51.49831867 ], [ -0.01280013, 51.49799682 ], [ -0.01313745, 51.49823179 ], [ -0.01367895, 51.49824602 ], [ -0.01339919, 51.4997711 ], [ -0.01123124, 51.49956335 ], [ -0.010581, 51.49960627 ], [ -0.01031857, 51.50038808 ], [ -0.0103747, 51.50051861 ], [ -0.01020802, 51.50097996 ], [ -0.01040341, 51.50100017 ], [ -0.01027622, 51.50131203 ], [ -0.00975359, 51.50128147 ], [ -0.00971183, 51.50158395 ], [ -0.00914341, 51.50151534 ], [ -0.0087192, 51.50166101 ], [ -0.00872028, 51.50196679 ], [ -0.00842584, 51.50277115 ], [ -0.00776009, 51.50397127 ], [ -0.00782959, 51.50421786 ], [ -0.00762907, 51.50452021 ], [ -0.00749871, 51.50453598 ], [ -0.00732894, 51.50479389 ], [ -0.00727414, 51.50505892 ], [ -0.0071733, 51.50498227 ], [ -0.00716864, 51.50464108 ], [ -0.0068175, 51.50430716 ], [ -0.00582312, 51.50376808 ], [ -0.00551775, 51.5036623 ], [ -0.00396095, 51.50350024 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 22, "LSOA11CD": "E01004233", "LSOA11NM": "Tower Hamlets 003D", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1821, "HHOLDRES": 1821, "COMESTRES": 0, "POPDEN": 218.900000, "HHOLDS": 751, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.03459393, 51.53232489, -0.02681393, 51.53715488 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02787925, 51.53557448 ], [ -0.02732065, 51.53469132 ], [ -0.02681393, 51.53407128 ], [ -0.02759082, 51.53377859 ], [ -0.0283817, 51.53349513 ], [ -0.0297861, 51.53295723 ], [ -0.03060212, 51.53270802 ], [ -0.03205095, 51.53233373 ], [ -0.03224095, 51.53232489 ], [ -0.0325145, 51.53275776 ], [ -0.03328074, 51.53384547 ], [ -0.03405297, 51.53489344 ], [ -0.03364054, 51.5350113 ], [ -0.03429752, 51.53601517 ], [ -0.03459393, 51.53626947 ], [ -0.03422446, 51.53643492 ], [ -0.03275949, 51.53696791 ], [ -0.03233329, 51.53715488 ], [ -0.03218753, 51.53697169 ], [ -0.03290203, 51.53663763 ], [ -0.03258184, 51.53612122 ], [ -0.03196516, 51.53629689 ], [ -0.03157529, 51.53612843 ], [ -0.03161195, 51.53602349 ], [ -0.03112676, 51.53604124 ], [ -0.03099866, 51.53578757 ], [ -0.03061356, 51.53581726 ], [ -0.03043346, 51.53616008 ], [ -0.03004185, 51.53627196 ], [ -0.02974459, 51.53565832 ], [ -0.03052857, 51.53556637 ], [ -0.03031139, 51.535311 ], [ -0.03059786, 51.53509339 ], [ -0.03063029, 51.53474972 ], [ -0.03052831, 51.53456501 ], [ -0.03003056, 51.53439507 ], [ -0.02973089, 51.53437481 ], [ -0.02961893, 51.53423821 ], [ -0.0293768, 51.53419318 ], [ -0.02893223, 51.53425371 ], [ -0.02926312, 51.53478692 ], [ -0.03008637, 51.53475579 ], [ -0.03000778, 51.53524008 ], [ -0.02924664, 51.53542962 ], [ -0.0287288, 51.53540228 ], [ -0.02842718, 51.53554131 ], [ -0.02787925, 51.53557448 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 23, "LSOA11CD": "E01001848", "LSOA11NM": "Hackney 018C", "MSOA11CD": "E02000362", "MSOA11NM": "Hackney 018", "LAD11CD": "E09000012", "LAD11NM": "Hackney", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1654, "HHOLDRES": 1605, "COMESTRES": 49, "POPDEN": 109.100000, "HHOLDS": 655, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.04071535, 51.53419318, -0.02594873, 51.54459039 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02731481, 51.54260139 ], [ -0.02704284, 51.54211469 ], [ -0.02677369, 51.54200225 ], [ -0.02682548, 51.54180527 ], [ -0.02619405, 51.54073351 ], [ -0.02594873, 51.53985316 ], [ -0.02717337, 51.53932421 ], [ -0.02676099, 51.53896248 ], [ -0.02736937, 51.53870674 ], [ -0.02750546, 51.53852586 ], [ -0.02730434, 51.53818085 ], [ -0.02806622, 51.53810383 ], [ -0.02803011, 51.53779678 ], [ -0.02759495, 51.53782169 ], [ -0.02751424, 51.5376369 ], [ -0.02805816, 51.53753707 ], [ -0.02841642, 51.53739967 ], [ -0.02846495, 51.53722336 ], [ -0.02775862, 51.53723465 ], [ -0.02773235, 51.53691388 ], [ -0.02849223, 51.53669885 ], [ -0.02824533, 51.53631657 ], [ -0.02773178, 51.53635833 ], [ -0.02747665, 51.5360098 ], [ -0.02747287, 51.53589559 ], [ -0.02799137, 51.53585367 ], [ -0.02787925, 51.53557448 ], [ -0.02842718, 51.53554131 ], [ -0.0287288, 51.53540228 ], [ -0.02924664, 51.53542962 ], [ -0.03000778, 51.53524008 ], [ -0.03008637, 51.53475579 ], [ -0.02926312, 51.53478692 ], [ -0.02893223, 51.53425371 ], [ -0.0293768, 51.53419318 ], [ -0.02961893, 51.53423821 ], [ -0.02973089, 51.53437481 ], [ -0.03003056, 51.53439507 ], [ -0.03052831, 51.53456501 ], [ -0.03063029, 51.53474972 ], [ -0.03059786, 51.53509339 ], [ -0.03031139, 51.535311 ], [ -0.03052857, 51.53556637 ], [ -0.02974459, 51.53565832 ], [ -0.03004185, 51.53627196 ], [ -0.03043346, 51.53616008 ], [ -0.03061356, 51.53581726 ], [ -0.03099866, 51.53578757 ], [ -0.03112676, 51.53604124 ], [ -0.03161195, 51.53602349 ], [ -0.03157529, 51.53612843 ], [ -0.03196516, 51.53629689 ], [ -0.03258184, 51.53612122 ], [ -0.03290203, 51.53663763 ], [ -0.03218753, 51.53697169 ], [ -0.03233329, 51.53715488 ], [ -0.03275949, 51.53696791 ], [ -0.03422446, 51.53643492 ], [ -0.03459393, 51.53626947 ], [ -0.0349395, 51.53657323 ], [ -0.03541267, 51.53676114 ], [ -0.03589183, 51.53708209 ], [ -0.03639341, 51.53757315 ], [ -0.03716572, 51.53793104 ], [ -0.0377773, 51.53796094 ], [ -0.03873368, 51.53785301 ], [ -0.03897466, 51.53786603 ], [ -0.03970996, 51.53807897 ], [ -0.04041918, 51.53799696 ], [ -0.04071535, 51.53804701 ], [ -0.04008473, 51.53862789 ], [ -0.03909175, 51.53958687 ], [ -0.03803539, 51.54053073 ], [ -0.0371477, 51.54136569 ], [ -0.03774178, 51.54174069 ], [ -0.03628194, 51.54263267 ], [ -0.03549627, 51.54308559 ], [ -0.03468215, 51.54346651 ], [ -0.03376511, 51.54422692 ], [ -0.03365476, 51.54440295 ], [ -0.03320138, 51.54459039 ], [ -0.03295631, 51.54456702 ], [ -0.0325362, 51.54427545 ], [ -0.03112792, 51.54342658 ], [ -0.030022, 51.54315369 ], [ -0.02972754, 51.54304266 ], [ -0.02940655, 51.54281568 ], [ -0.02906763, 51.54223177 ], [ -0.02801539, 51.54242766 ], [ -0.02731481, 51.54260139 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 24, "LSOA11CD": "E01033579", "LSOA11NM": "Newham 013F", "MSOA11CD": "E02000726", "MSOA11NM": "Newham 013", "LAD11CD": "E09000025", "LAD11NM": "Newham", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1293, "HHOLDRES": 1293, "COMESTRES": 0, "POPDEN": 29.400000, "HHOLDS": 618, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.02849223, 51.53206641, -0.01611056, 51.54348863 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01899154, 51.53904899 ], [ -0.01991473, 51.5392335 ], [ -0.01994729, 51.53945915 ], [ -0.02010619, 51.53945284 ], [ -0.02009814, 51.53927015 ], [ -0.02058446, 51.53936735 ], [ -0.02120581, 51.53997001 ], [ -0.02166522, 51.53974893 ], [ -0.02159629, 51.53967583 ], [ -0.02170263, 51.53921899 ], [ -0.02363164, 51.53829827 ], [ -0.02411576, 51.53910679 ], [ -0.02516145, 51.53860282 ], [ -0.02559255, 51.53797159 ], [ -0.02518672, 51.53768598 ], [ -0.02433965, 51.53726704 ], [ -0.02414726, 51.53704797 ], [ -0.02393422, 51.5366397 ], [ -0.02369705, 51.53645584 ], [ -0.02371404, 51.53628527 ], [ -0.0239962, 51.5358125 ], [ -0.02457277, 51.53580543 ], [ -0.02520376, 51.53564659 ], [ -0.02548249, 51.53607872 ], [ -0.02654337, 51.53597193 ], [ -0.02586732, 51.53495463 ], [ -0.02545345, 51.53440159 ], [ -0.02502026, 51.53387023 ], [ -0.0246725, 51.53359247 ], [ -0.02430253, 51.53279699 ], [ -0.02442441, 51.53264616 ], [ -0.02554082, 51.53217036 ], [ -0.02577602, 51.53206641 ], [ -0.02623204, 51.53252372 ], [ -0.02762038, 51.53376109 ], [ -0.02759082, 51.53377859 ], [ -0.02681393, 51.53407128 ], [ -0.02732065, 51.53469132 ], [ -0.02787925, 51.53557448 ], [ -0.02799137, 51.53585367 ], [ -0.02747287, 51.53589559 ], [ -0.02747665, 51.5360098 ], [ -0.02773178, 51.53635833 ], [ -0.02824533, 51.53631657 ], [ -0.02849223, 51.53669885 ], [ -0.02773235, 51.53691388 ], [ -0.02775862, 51.53723465 ], [ -0.02846495, 51.53722336 ], [ -0.02841642, 51.53739967 ], [ -0.02805816, 51.53753707 ], [ -0.02751424, 51.5376369 ], [ -0.02759495, 51.53782169 ], [ -0.02803011, 51.53779678 ], [ -0.02806622, 51.53810383 ], [ -0.02730434, 51.53818085 ], [ -0.02750546, 51.53852586 ], [ -0.02736937, 51.53870674 ], [ -0.02676099, 51.53896248 ], [ -0.02717337, 51.53932421 ], [ -0.02594873, 51.53985316 ], [ -0.02619405, 51.54073351 ], [ -0.02682548, 51.54180527 ], [ -0.02677369, 51.54200225 ], [ -0.02704284, 51.54211469 ], [ -0.02731481, 51.54260139 ], [ -0.02648482, 51.54284566 ], [ -0.02574078, 51.54310475 ], [ -0.02561235, 51.54323973 ], [ -0.02533081, 51.54316375 ], [ -0.02307465, 51.54333062 ], [ -0.02158843, 51.54338971 ], [ -0.02070867, 51.54345173 ], [ -0.01936492, 51.54348863 ], [ -0.01827048, 51.54342983 ], [ -0.016482, 51.54322577 ], [ -0.01643477, 51.54294381 ], [ -0.01611056, 51.54246294 ], [ -0.01637899, 51.54178097 ], [ -0.01647985, 51.54134807 ], [ -0.01678023, 51.54115601 ], [ -0.01745465, 51.54098502 ], [ -0.01768495, 51.54070494 ], [ -0.01772099, 51.54033207 ], [ -0.01788729, 51.5400311 ], [ -0.01881655, 51.53934619 ], [ -0.01899154, 51.53904899 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 25, "LSOA11CD": "E01004237", "LSOA11NM": "Tower Hamlets 008C", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1158, "HHOLDRES": 1158, "COMESTRES": 0, "POPDEN": 177.300000, "HHOLDS": 506, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.02349718, 51.52787417, -0.01732586, 51.53235258 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0190385, 51.52808353 ], [ -0.02000372, 51.52800523 ], [ -0.02101231, 51.52787417 ], [ -0.02149298, 51.52848816 ], [ -0.02206057, 51.52911402 ], [ -0.02220719, 51.52951499 ], [ -0.02279858, 51.53031998 ], [ -0.02298442, 51.53027528 ], [ -0.02349718, 51.53117022 ], [ -0.02324253, 51.53125393 ], [ -0.02304911, 51.5315894 ], [ -0.02289464, 51.53157417 ], [ -0.02191146, 51.53215511 ], [ -0.02157724, 51.53235258 ], [ -0.02086494, 51.53191232 ], [ -0.02042824, 51.53220585 ], [ -0.02030951, 51.53210274 ], [ -0.01988759, 51.53226566 ], [ -0.0180689, 51.5312506 ], [ -0.01818547, 51.53088623 ], [ -0.01739796, 51.53043654 ], [ -0.01732586, 51.53009132 ], [ -0.01734677, 51.52978893 ], [ -0.0179901, 51.52956098 ], [ -0.01809498, 51.52918412 ], [ -0.01869113, 51.5297554 ], [ -0.01932598, 51.52945042 ], [ -0.01922361, 51.52932931 ], [ -0.01969999, 51.52922337 ], [ -0.01963499, 51.52903753 ], [ -0.01939571, 51.52884844 ], [ -0.01892129, 51.52870356 ], [ -0.01918022, 51.52817658 ], [ -0.0190385, 51.52808353 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 26, "LSOA11CD": "E01004224", "LSOA11NM": "Tower Hamlets 001C", "MSOA11CD": "E02000864", "MSOA11NM": "Tower Hamlets 001", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2000, "HHOLDRES": 2000, "COMESTRES": 0, "POPDEN": 45.600000, "HHOLDS": 806, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.03224095, 51.52951931, -0.02577602, 51.53377859 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02577602, 51.53206641 ], [ -0.02636059, 51.531756 ], [ -0.02594593, 51.53152007 ], [ -0.02641769, 51.53127365 ], [ -0.02676046, 51.5315338 ], [ -0.02703062, 51.53139507 ], [ -0.0275825, 51.53174837 ], [ -0.02804847, 51.53187325 ], [ -0.02842069, 51.53215067 ], [ -0.02901001, 51.53196792 ], [ -0.02862009, 51.53149462 ], [ -0.0287176, 51.53136578 ], [ -0.02854644, 51.5310385 ], [ -0.02903246, 51.53079496 ], [ -0.0288272, 51.530526 ], [ -0.02944629, 51.53025801 ], [ -0.02909708, 51.53009122 ], [ -0.03001459, 51.52951931 ], [ -0.03048539, 51.5300369 ], [ -0.0317062, 51.53153068 ], [ -0.03224095, 51.53232489 ], [ -0.03205095, 51.53233373 ], [ -0.03060212, 51.53270802 ], [ -0.0297861, 51.53295723 ], [ -0.0283817, 51.53349513 ], [ -0.02759082, 51.53377859 ], [ -0.02762038, 51.53376109 ], [ -0.02623204, 51.53252372 ], [ -0.02577602, 51.53206641 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 27, "LSOA11CD": "E01004233", "LSOA11NM": "Tower Hamlets 003D", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1821, "HHOLDRES": 1821, "COMESTRES": 0, "POPDEN": 218.900000, "HHOLDS": 751, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.03711931, 51.52765369, -0.03048539, 51.53288168 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03224095, 51.53232489 ], [ -0.0317062, 51.53153068 ], [ -0.03048539, 51.5300369 ], [ -0.03089014, 51.52996988 ], [ -0.03185215, 51.5296618 ], [ -0.03239872, 51.5297427 ], [ -0.03207684, 51.52939352 ], [ -0.03172674, 51.52915384 ], [ -0.0310584, 51.52827032 ], [ -0.03081868, 51.52786113 ], [ -0.03146152, 51.52799916 ], [ -0.03155998, 51.52818973 ], [ -0.03183373, 51.52825597 ], [ -0.03213454, 51.52802994 ], [ -0.03198936, 51.52778981 ], [ -0.03251923, 51.5277776 ], [ -0.03315814, 51.52765369 ], [ -0.03349781, 51.52820333 ], [ -0.03367539, 51.52858838 ], [ -0.03334582, 51.52868208 ], [ -0.03335699, 51.52879449 ], [ -0.03455153, 51.52850876 ], [ -0.03494594, 51.52838947 ], [ -0.03675472, 51.52795256 ], [ -0.03706114, 51.52827299 ], [ -0.03687995, 51.52834093 ], [ -0.03711931, 51.52859279 ], [ -0.03560305, 51.52916199 ], [ -0.03498718, 51.52934211 ], [ -0.03475022, 51.52933246 ], [ -0.03454742, 51.52944327 ], [ -0.03425533, 51.52945918 ], [ -0.03417782, 51.52964563 ], [ -0.03438488, 51.52989469 ], [ -0.03424221, 51.53006664 ], [ -0.03455335, 51.53019096 ], [ -0.03462374, 51.53033544 ], [ -0.0348809, 51.53026056 ], [ -0.03493001, 51.53043188 ], [ -0.03513106, 51.53052879 ], [ -0.03513618, 51.5306764 ], [ -0.0353293, 51.53086035 ], [ -0.03525801, 51.53107215 ], [ -0.03556591, 51.53145155 ], [ -0.03600226, 51.53136301 ], [ -0.03625541, 51.53123423 ], [ -0.03658227, 51.53157335 ], [ -0.03511507, 51.53182755 ], [ -0.03295536, 51.53222156 ], [ -0.03278628, 51.53245841 ], [ -0.03320596, 51.53247965 ], [ -0.03363454, 51.53240742 ], [ -0.03382619, 51.53262862 ], [ -0.03326314, 51.53271923 ], [ -0.03266621, 51.53288168 ], [ -0.0325145, 51.53275776 ], [ -0.03224095, 51.53232489 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 28, "LSOA11CD": "E01032784", "LSOA11NM": "Tower Hamlets 004G", "MSOA11CD": "E02000867", "MSOA11NM": "Tower Hamlets 004", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1516, "HHOLDRES": 1516, "COMESTRES": 0, "POPDEN": 234.000000, "HHOLDS": 692, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.03239872, 51.52611055, -0.02654365, 51.5300369 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03001459, 51.52951931 ], [ -0.02988188, 51.52934895 ], [ -0.0286078, 51.52949292 ], [ -0.02722757, 51.52961349 ], [ -0.0269214, 51.52925295 ], [ -0.02654365, 51.52865307 ], [ -0.0270825, 51.52848185 ], [ -0.02690803, 51.52815904 ], [ -0.02702328, 51.52798518 ], [ -0.02738187, 51.52814035 ], [ -0.02764031, 51.52808052 ], [ -0.02725937, 51.52766516 ], [ -0.02721158, 51.52746874 ], [ -0.02676845, 51.52677945 ], [ -0.02688918, 51.52672166 ], [ -0.0279591, 51.52648972 ], [ -0.02980691, 51.52611055 ], [ -0.03003851, 51.52651178 ], [ -0.03030949, 51.52641755 ], [ -0.03061593, 51.52647366 ], [ -0.03112939, 51.52735153 ], [ -0.03097979, 51.52750453 ], [ -0.03065718, 51.52757216 ], [ -0.03081868, 51.52786113 ], [ -0.0310584, 51.52827032 ], [ -0.03172674, 51.52915384 ], [ -0.03207684, 51.52939352 ], [ -0.03239872, 51.5297427 ], [ -0.03185215, 51.5296618 ], [ -0.03089014, 51.52996988 ], [ -0.03048539, 51.5300369 ], [ -0.03001459, 51.52951931 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 29, "LSOA11CD": "E01004234", "LSOA11NM": "Tower Hamlets 003E", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2218, "HHOLDRES": 2218, "COMESTRES": 0, "POPDEN": 38.700000, "HHOLDS": 903, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.04220901, 51.52725139, -0.03417782, 51.53182685 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03658227, 51.53157335 ], [ -0.03625541, 51.53123423 ], [ -0.03600226, 51.53136301 ], [ -0.03556591, 51.53145155 ], [ -0.03525801, 51.53107215 ], [ -0.0353293, 51.53086035 ], [ -0.03513618, 51.5306764 ], [ -0.03513106, 51.53052879 ], [ -0.03493001, 51.53043188 ], [ -0.0348809, 51.53026056 ], [ -0.03462374, 51.53033544 ], [ -0.03455335, 51.53019096 ], [ -0.03424221, 51.53006664 ], [ -0.03438488, 51.52989469 ], [ -0.03417782, 51.52964563 ], [ -0.03425533, 51.52945918 ], [ -0.03454742, 51.52944327 ], [ -0.03475022, 51.52933246 ], [ -0.03498718, 51.52934211 ], [ -0.03560305, 51.52916199 ], [ -0.03711931, 51.52859279 ], [ -0.03687995, 51.52834093 ], [ -0.03706114, 51.52827299 ], [ -0.03675472, 51.52795256 ], [ -0.03733496, 51.52781797 ], [ -0.04000349, 51.5273419 ], [ -0.03994505, 51.52725139 ], [ -0.04061639, 51.52824393 ], [ -0.04137642, 51.5291788 ], [ -0.04220901, 51.53033262 ], [ -0.04021938, 51.53081584 ], [ -0.0397759, 51.53097279 ], [ -0.03984527, 51.53111615 ], [ -0.03950442, 51.53130819 ], [ -0.03928367, 51.53126321 ], [ -0.03909652, 51.53139744 ], [ -0.03885263, 51.53136365 ], [ -0.03835974, 51.53145997 ], [ -0.03824498, 51.53155067 ], [ -0.0383236, 51.53173787 ], [ -0.03790755, 51.53182685 ], [ -0.03765888, 51.53134856 ], [ -0.03658227, 51.53157335 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 30, "LSOA11CD": "E01004237", "LSOA11NM": "Tower Hamlets 008C", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1158, "HHOLDRES": 1158, "COMESTRES": 0, "POPDEN": 177.300000, "HHOLDS": 506, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.02764031, 51.52672166, -0.02101231, 51.53031998 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02101231, 51.52787417 ], [ -0.02178707, 51.52777426 ], [ -0.02268094, 51.52760722 ], [ -0.02319645, 51.52748018 ], [ -0.02451992, 51.52723523 ], [ -0.02571985, 51.52697513 ], [ -0.02688918, 51.52672166 ], [ -0.02676845, 51.52677945 ], [ -0.02721158, 51.52746874 ], [ -0.02725937, 51.52766516 ], [ -0.02764031, 51.52808052 ], [ -0.02738187, 51.52814035 ], [ -0.02702328, 51.52798518 ], [ -0.02690803, 51.52815904 ], [ -0.0270825, 51.52848185 ], [ -0.02654365, 51.52865307 ], [ -0.0269214, 51.52925295 ], [ -0.02722757, 51.52961349 ], [ -0.02687986, 51.5296448 ], [ -0.02599936, 51.52973696 ], [ -0.02500745, 51.52987791 ], [ -0.02363133, 51.53012999 ], [ -0.02298442, 51.53027528 ], [ -0.02279858, 51.53031998 ], [ -0.02220719, 51.52951499 ], [ -0.02206057, 51.52911402 ], [ -0.02149298, 51.52848816 ], [ -0.02101231, 51.52787417 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 31, "LSOA11CD": "E01004232", "LSOA11NM": "Tower Hamlets 003C", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1665, "HHOLDRES": 1631, "COMESTRES": 34, "POPDEN": 86.100000, "HHOLDS": 603, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.04000349, 51.52418232, -0.02980691, 51.52879449 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03081868, 51.52786113 ], [ -0.03065718, 51.52757216 ], [ -0.03097979, 51.52750453 ], [ -0.03112939, 51.52735153 ], [ -0.03061593, 51.52647366 ], [ -0.03030949, 51.52641755 ], [ -0.03003851, 51.52651178 ], [ -0.02980691, 51.52611055 ], [ -0.03366534, 51.52525636 ], [ -0.03490031, 51.52494088 ], [ -0.03573774, 51.52469026 ], [ -0.03707324, 51.52418232 ], [ -0.03811627, 51.52517521 ], [ -0.03874176, 51.52573719 ], [ -0.03941501, 51.52646702 ], [ -0.03974306, 51.52694225 ], [ -0.03994505, 51.52725139 ], [ -0.04000349, 51.5273419 ], [ -0.03733496, 51.52781797 ], [ -0.03675472, 51.52795256 ], [ -0.03494594, 51.52838947 ], [ -0.03455153, 51.52850876 ], [ -0.03335699, 51.52879449 ], [ -0.03334582, 51.52868208 ], [ -0.03367539, 51.52858838 ], [ -0.03349781, 51.52820333 ], [ -0.03315814, 51.52765369 ], [ -0.03251923, 51.5277776 ], [ -0.03198936, 51.52778981 ], [ -0.03213454, 51.52802994 ], [ -0.03183373, 51.52825597 ], [ -0.03155998, 51.52818973 ], [ -0.03146152, 51.52799916 ], [ -0.03081868, 51.52786113 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 32, "LSOA11CD": "E01004233", "LSOA11NM": "Tower Hamlets 003D", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1821, "HHOLDRES": 1821, "COMESTRES": 0, "POPDEN": 218.900000, "HHOLDS": 751, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.03732293, 51.53219332, -0.0325145, 51.53626947 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0325145, 51.53275776 ], [ -0.03266621, 51.53288168 ], [ -0.03326314, 51.53271923 ], [ -0.03382619, 51.53262862 ], [ -0.03363454, 51.53240742 ], [ -0.03390065, 51.5323046 ], [ -0.03423083, 51.53230131 ], [ -0.03446698, 51.5324074 ], [ -0.03533555, 51.53219332 ], [ -0.03585789, 51.53306032 ], [ -0.03617144, 51.53324885 ], [ -0.03625359, 51.53296503 ], [ -0.036633, 51.53287366 ], [ -0.03732293, 51.5341307 ], [ -0.03670781, 51.5342691 ], [ -0.03712874, 51.53462702 ], [ -0.0366327, 51.53489398 ], [ -0.03684249, 51.53506706 ], [ -0.03585091, 51.53549994 ], [ -0.03472408, 51.53621848 ], [ -0.03459393, 51.53626947 ], [ -0.03429752, 51.53601517 ], [ -0.03364054, 51.5350113 ], [ -0.03405297, 51.53489344 ], [ -0.03328074, 51.53384547 ], [ -0.0325145, 51.53275776 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 33, "LSOA11CD": "E01001837", "LSOA11NM": "Hackney 023B", "MSOA11CD": "E02000367", "MSOA11NM": "Hackney 023", "LAD11CD": "E09000012", "LAD11NM": "Hackney", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1488, "HHOLDRES": 1478, "COMESTRES": 10, "POPDEN": 133.600000, "HHOLDS": 665, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.05281954, 51.53033262, -0.03278628, 51.53807897 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03459393, 51.53626947 ], [ -0.03472408, 51.53621848 ], [ -0.03585091, 51.53549994 ], [ -0.03684249, 51.53506706 ], [ -0.0366327, 51.53489398 ], [ -0.03712874, 51.53462702 ], [ -0.03670781, 51.5342691 ], [ -0.03732293, 51.5341307 ], [ -0.036633, 51.53287366 ], [ -0.03625359, 51.53296503 ], [ -0.03617144, 51.53324885 ], [ -0.03585789, 51.53306032 ], [ -0.03533555, 51.53219332 ], [ -0.03446698, 51.5324074 ], [ -0.03423083, 51.53230131 ], [ -0.03390065, 51.5323046 ], [ -0.03363454, 51.53240742 ], [ -0.03320596, 51.53247965 ], [ -0.03278628, 51.53245841 ], [ -0.03295536, 51.53222156 ], [ -0.03511507, 51.53182755 ], [ -0.03658227, 51.53157335 ], [ -0.03765888, 51.53134856 ], [ -0.03790755, 51.53182685 ], [ -0.0383236, 51.53173787 ], [ -0.03824498, 51.53155067 ], [ -0.03835974, 51.53145997 ], [ -0.03885263, 51.53136365 ], [ -0.03909652, 51.53139744 ], [ -0.03928367, 51.53126321 ], [ -0.03950442, 51.53130819 ], [ -0.03984527, 51.53111615 ], [ -0.0397759, 51.53097279 ], [ -0.04021938, 51.53081584 ], [ -0.04220901, 51.53033262 ], [ -0.04247852, 51.53064757 ], [ -0.04294193, 51.53104158 ], [ -0.04334451, 51.53125667 ], [ -0.04448662, 51.53179564 ], [ -0.0455975, 51.53236845 ], [ -0.04647939, 51.53273442 ], [ -0.05253844, 51.53474902 ], [ -0.05281954, 51.53483512 ], [ -0.0526894, 51.53547707 ], [ -0.05237291, 51.53586104 ], [ -0.0518597, 51.53616599 ], [ -0.05140925, 51.53633092 ], [ -0.050633, 51.536422 ], [ -0.05022843, 51.53639898 ], [ -0.04952972, 51.5362571 ], [ -0.04888191, 51.53593706 ], [ -0.04828983, 51.53559911 ], [ -0.04755429, 51.53547615 ], [ -0.04690172, 51.53543606 ], [ -0.04596136, 51.53555022 ], [ -0.04490432, 51.53573719 ], [ -0.04462186, 51.53585108 ], [ -0.04394893, 51.53637097 ], [ -0.04355619, 51.53640716 ], [ -0.04143878, 51.53736102 ], [ -0.04071535, 51.53804701 ], [ -0.04041918, 51.53799696 ], [ -0.03970996, 51.53807897 ], [ -0.03897466, 51.53786603 ], [ -0.03873368, 51.53785301 ], [ -0.0377773, 51.53796094 ], [ -0.03716572, 51.53793104 ], [ -0.03639341, 51.53757315 ], [ -0.03589183, 51.53708209 ], [ -0.03541267, 51.53676114 ], [ -0.0349395, 51.53657323 ], [ -0.03459393, 51.53626947 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 34, "LSOA11CD": "E01004235", "LSOA11NM": "Tower Hamlets 008A", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1372, "HHOLDRES": 1372, "COMESTRES": 0, "POPDEN": 345.600000, "HHOLDS": 513, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.01780173, 51.52734261, -0.0130973, 51.52975439 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01619107, 51.52737472 ], [ -0.01573822, 51.52773306 ], [ -0.01570001, 51.52784859 ], [ -0.01636277, 51.52770793 ], [ -0.01724627, 51.52761496 ], [ -0.0174717, 51.52773567 ], [ -0.01780028, 51.52813691 ], [ -0.01780173, 51.52826377 ], [ -0.01645267, 51.52862517 ], [ -0.01581644, 51.5288752 ], [ -0.01523716, 51.5291831 ], [ -0.01461511, 51.52943814 ], [ -0.01371535, 51.52975439 ], [ -0.01358309, 51.52963031 ], [ -0.01366295, 51.52945181 ], [ -0.01337329, 51.52929148 ], [ -0.01356316, 51.52919197 ], [ -0.0130973, 51.52886669 ], [ -0.01316354, 51.52866997 ], [ -0.01356426, 51.52840697 ], [ -0.01393108, 51.5282603 ], [ -0.0150677, 51.52798278 ], [ -0.01497751, 51.5277702 ], [ -0.01541347, 51.52746368 ], [ -0.01591497, 51.52734261 ], [ -0.01619107, 51.52737472 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 35, "LSOA11CD": "E01004235", "LSOA11NM": "Tower Hamlets 008A", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1372, "HHOLDRES": 1372, "COMESTRES": 0, "POPDEN": 345.600000, "HHOLDS": 513, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.01686355, 51.5244986, -0.01066308, 51.52886669 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01519016, 51.52450463 ], [ -0.01601605, 51.52452867 ], [ -0.01654777, 51.52495684 ], [ -0.0157507, 51.52520656 ], [ -0.01633694, 51.52598087 ], [ -0.01663942, 51.52631872 ], [ -0.01609906, 51.52645816 ], [ -0.01676474, 51.52688921 ], [ -0.01686355, 51.52708601 ], [ -0.01671847, 51.52722063 ], [ -0.01619107, 51.52737472 ], [ -0.01591497, 51.52734261 ], [ -0.01541347, 51.52746368 ], [ -0.01497751, 51.5277702 ], [ -0.0150677, 51.52798278 ], [ -0.01393108, 51.5282603 ], [ -0.01356426, 51.52840697 ], [ -0.01316354, 51.52866997 ], [ -0.0130973, 51.52886669 ], [ -0.01279252, 51.52864759 ], [ -0.01246543, 51.52873332 ], [ -0.01184602, 51.52813505 ], [ -0.01172005, 51.52792318 ], [ -0.01156226, 51.52796703 ], [ -0.01084831, 51.52720985 ], [ -0.01066308, 51.52682901 ], [ -0.01072001, 51.52651523 ], [ -0.0111753, 51.52599237 ], [ -0.01148048, 51.52601895 ], [ -0.0115628, 51.52577635 ], [ -0.01177817, 51.52581702 ], [ -0.0120257, 51.52615954 ], [ -0.0124264, 51.52596461 ], [ -0.01266073, 51.52603035 ], [ -0.01260778, 51.52623357 ], [ -0.01269605, 51.52644845 ], [ -0.0135573, 51.52624856 ], [ -0.01437806, 51.52627146 ], [ -0.01443861, 51.52599797 ], [ -0.01471817, 51.52549903 ], [ -0.01463257, 51.52535492 ], [ -0.01490352, 51.52518601 ], [ -0.01462544, 51.52475967 ], [ -0.01434289, 51.52462954 ], [ -0.01429751, 51.5244986 ], [ -0.01519016, 51.52450463 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 36, "LSOA11CD": "E01004235", "LSOA11NM": "Tower Hamlets 008A", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1372, "HHOLDRES": 1372, "COMESTRES": 0, "POPDEN": 345.600000, "HHOLDS": 513, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02101231, 51.52460702, -0.01570001, 51.52826377 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01619107, 51.52737472 ], [ -0.01671847, 51.52722063 ], [ -0.01686355, 51.52708601 ], [ -0.01676474, 51.52688921 ], [ -0.01609906, 51.52645816 ], [ -0.01663942, 51.52631872 ], [ -0.01730112, 51.52614777 ], [ -0.01744222, 51.52623398 ], [ -0.01787035, 51.52619583 ], [ -0.01842433, 51.52592627 ], [ -0.01891217, 51.52581113 ], [ -0.0184867, 51.52558248 ], [ -0.01830676, 51.52526406 ], [ -0.01827426, 51.52504586 ], [ -0.01846209, 51.52473955 ], [ -0.01885339, 51.52460702 ], [ -0.01912275, 51.5250306 ], [ -0.01904809, 51.52504845 ], [ -0.02022701, 51.52684626 ], [ -0.02028532, 51.52683137 ], [ -0.02101231, 51.52787417 ], [ -0.02000372, 51.52800523 ], [ -0.0190385, 51.52808353 ], [ -0.01780173, 51.52826377 ], [ -0.01780028, 51.52813691 ], [ -0.0174717, 51.52773567 ], [ -0.01724627, 51.52761496 ], [ -0.01636277, 51.52770793 ], [ -0.01570001, 51.52784859 ], [ -0.01573822, 51.52773306 ], [ -0.01619107, 51.52737472 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 37, "LSOA11CD": "E01004235", "LSOA11NM": "Tower Hamlets 008A", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1372, "HHOLDRES": 1372, "COMESTRES": 0, "POPDEN": 345.600000, "HHOLDS": 513, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.01609765, 51.51973151, -0.00735395, 51.52978615 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00809977, 51.52368677 ], [ -0.00851127, 51.52296984 ], [ -0.00905945, 51.52232098 ], [ -0.0101891, 51.52162199 ], [ -0.01107946, 51.52103809 ], [ -0.01133814, 51.5208081 ], [ -0.01186525, 51.52051704 ], [ -0.0126858, 51.52023207 ], [ -0.01383182, 51.51973151 ], [ -0.0154188, 51.52081108 ], [ -0.01590854, 51.52157613 ], [ -0.0160704, 51.52200226 ], [ -0.01609765, 51.52219984 ], [ -0.01604111, 51.52283737 ], [ -0.01492567, 51.52296238 ], [ -0.01497899, 51.52306221 ], [ -0.01509328, 51.52408033 ], [ -0.01519016, 51.52450463 ], [ -0.01429751, 51.5244986 ], [ -0.01434289, 51.52462954 ], [ -0.01462544, 51.52475967 ], [ -0.01490352, 51.52518601 ], [ -0.01463257, 51.52535492 ], [ -0.01471817, 51.52549903 ], [ -0.01443861, 51.52599797 ], [ -0.01437806, 51.52627146 ], [ -0.0135573, 51.52624856 ], [ -0.01269605, 51.52644845 ], [ -0.01260778, 51.52623357 ], [ -0.01266073, 51.52603035 ], [ -0.0124264, 51.52596461 ], [ -0.0120257, 51.52615954 ], [ -0.01177817, 51.52581702 ], [ -0.0115628, 51.52577635 ], [ -0.01148048, 51.52601895 ], [ -0.0111753, 51.52599237 ], [ -0.01072001, 51.52651523 ], [ -0.01066308, 51.52682901 ], [ -0.01084831, 51.52720985 ], [ -0.01156226, 51.52796703 ], [ -0.01172005, 51.52792318 ], [ -0.01184602, 51.52813505 ], [ -0.01246543, 51.52873332 ], [ -0.01279252, 51.52864759 ], [ -0.0130973, 51.52886669 ], [ -0.01356316, 51.52919197 ], [ -0.01337329, 51.52929148 ], [ -0.01366295, 51.52945181 ], [ -0.01358309, 51.52963031 ], [ -0.01371535, 51.52975439 ], [ -0.01362497, 51.52978615 ], [ -0.01315248, 51.52964817 ], [ -0.01092941, 51.52938019 ], [ -0.01055598, 51.52912022 ], [ -0.01032475, 51.52853331 ], [ -0.00999977, 51.52827839 ], [ -0.00877608, 51.52765933 ], [ -0.00851519, 51.52742248 ], [ -0.00820886, 51.52684356 ], [ -0.00765511, 51.52638058 ], [ -0.00741092, 51.52609162 ], [ -0.00735395, 51.52591066 ], [ -0.00742524, 51.52563955 ], [ -0.00782816, 51.52503768 ], [ -0.00791506, 51.5248017 ], [ -0.00809977, 51.52368677 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 38, "LSOA11CD": "E01004236", "LSOA11NM": "Tower Hamlets 008B", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1679, "HHOLDRES": 1679, "COMESTRES": 0, "POPDEN": 164.300000, "HHOLDS": 497, "AVHHOLDSZ": 3.400000 }, "bbox": [ -0.0202073, 51.52113093, -0.01492567, 51.52631872 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01519016, 51.52450463 ], [ -0.01509328, 51.52408033 ], [ -0.01497899, 51.52306221 ], [ -0.01492567, 51.52296238 ], [ -0.01604111, 51.52283737 ], [ -0.01609765, 51.52219984 ], [ -0.0160704, 51.52200226 ], [ -0.01625093, 51.52173782 ], [ -0.01678, 51.52189205 ], [ -0.01736981, 51.52197193 ], [ -0.0177964, 51.52207658 ], [ -0.01808527, 51.52230052 ], [ -0.01872716, 51.5217317 ], [ -0.01899271, 51.52125957 ], [ -0.02007066, 51.52113093 ], [ -0.0202073, 51.52134707 ], [ -0.01974015, 51.52160603 ], [ -0.01941313, 51.52186919 ], [ -0.01946632, 51.52210799 ], [ -0.01947972, 51.52215863 ], [ -0.01884322, 51.52223687 ], [ -0.01905446, 51.52282229 ], [ -0.01865521, 51.52297571 ], [ -0.01897578, 51.52364238 ], [ -0.01948644, 51.52448161 ], [ -0.01876345, 51.52446556 ], [ -0.01885339, 51.52460702 ], [ -0.01846209, 51.52473955 ], [ -0.01827426, 51.52504586 ], [ -0.01830676, 51.52526406 ], [ -0.0184867, 51.52558248 ], [ -0.01891217, 51.52581113 ], [ -0.01842433, 51.52592627 ], [ -0.01787035, 51.52619583 ], [ -0.01744222, 51.52623398 ], [ -0.01730112, 51.52614777 ], [ -0.01663942, 51.52631872 ], [ -0.01633694, 51.52598087 ], [ -0.0157507, 51.52520656 ], [ -0.01654777, 51.52495684 ], [ -0.01601605, 51.52452867 ], [ -0.01519016, 51.52450463 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 39, "LSOA11CD": "E01004239", "LSOA11NM": "Tower Hamlets 008E", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1649, "HHOLDRES": 1649, "COMESTRES": 0, "POPDEN": 154.500000, "HHOLDS": 533, "AVHHOLDSZ": 3.100000 }, "bbox": [ -0.02442054, 51.52149151, -0.01865521, 51.52449257 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01946632, 51.52210799 ], [ -0.01996385, 51.52208469 ], [ -0.02034628, 51.52224563 ], [ -0.02051035, 51.52199037 ], [ -0.02042769, 51.52174243 ], [ -0.02074155, 51.5217034 ], [ -0.02111569, 51.5221691 ], [ -0.02125588, 51.52218507 ], [ -0.02158333, 51.52195004 ], [ -0.02194999, 51.52187632 ], [ -0.0222429, 51.52198305 ], [ -0.02237974, 51.52189362 ], [ -0.02256893, 51.52214706 ], [ -0.02235169, 51.52242296 ], [ -0.0225646, 51.52246256 ], [ -0.02284694, 51.52232699 ], [ -0.02308659, 51.52197959 ], [ -0.02284128, 51.52172246 ], [ -0.02315218, 51.52149151 ], [ -0.02403997, 51.52168573 ], [ -0.02442054, 51.52185281 ], [ -0.02412289, 51.52196628 ], [ -0.02393915, 51.52214797 ], [ -0.02407166, 51.52225379 ], [ -0.02439352, 51.52273695 ], [ -0.02347385, 51.52353055 ], [ -0.02284554, 51.52391255 ], [ -0.02189757, 51.52426851 ], [ -0.02131431, 51.52440058 ], [ -0.02030389, 51.52449257 ], [ -0.01948644, 51.52448161 ], [ -0.01897578, 51.52364238 ], [ -0.01865521, 51.52297571 ], [ -0.01905446, 51.52282229 ], [ -0.01884322, 51.52223687 ], [ -0.01947972, 51.52215863 ], [ -0.01946632, 51.52210799 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 40, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02735932, 51.51846628, -0.01941313, 51.52273695 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01946632, 51.52210799 ], [ -0.01941313, 51.52186919 ], [ -0.01974015, 51.52160603 ], [ -0.0202073, 51.52134707 ], [ -0.02007066, 51.52113093 ], [ -0.01967584, 51.52065805 ], [ -0.02046566, 51.5205683 ], [ -0.02029186, 51.52038175 ], [ -0.02043298, 51.52030666 ], [ -0.02073587, 51.52053341 ], [ -0.02134048, 51.52045536 ], [ -0.02124735, 51.51995715 ], [ -0.02260242, 51.51979171 ], [ -0.02260535, 51.51967486 ], [ -0.02284897, 51.51953087 ], [ -0.022184, 51.51908799 ], [ -0.0217933, 51.51923749 ], [ -0.02163343, 51.51910179 ], [ -0.02248057, 51.51861159 ], [ -0.0231217, 51.51846628 ], [ -0.0234534, 51.51898911 ], [ -0.02411616, 51.51945399 ], [ -0.02474955, 51.51971634 ], [ -0.02586026, 51.52010092 ], [ -0.02683627, 51.52057289 ], [ -0.02735932, 51.52070142 ], [ -0.02678893, 51.52104281 ], [ -0.02439352, 51.52273695 ], [ -0.02407166, 51.52225379 ], [ -0.02393915, 51.52214797 ], [ -0.02412289, 51.52196628 ], [ -0.02442054, 51.52185281 ], [ -0.02403997, 51.52168573 ], [ -0.02315218, 51.52149151 ], [ -0.02284128, 51.52172246 ], [ -0.02308659, 51.52197959 ], [ -0.02284694, 51.52232699 ], [ -0.0225646, 51.52246256 ], [ -0.02235169, 51.52242296 ], [ -0.02256893, 51.52214706 ], [ -0.02237974, 51.52189362 ], [ -0.0222429, 51.52198305 ], [ -0.02194999, 51.52187632 ], [ -0.02158333, 51.52195004 ], [ -0.02125588, 51.52218507 ], [ -0.02111569, 51.5221691 ], [ -0.02074155, 51.5217034 ], [ -0.02042769, 51.52174243 ], [ -0.02051035, 51.52199037 ], [ -0.02034628, 51.52224563 ], [ -0.01996385, 51.52208469 ], [ -0.01946632, 51.52210799 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 41, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.0231217, 51.51654128, -0.01383182, 51.52230052 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0160704, 51.52200226 ], [ -0.01590854, 51.52157613 ], [ -0.0154188, 51.52081108 ], [ -0.01383182, 51.51973151 ], [ -0.0142345, 51.51955805 ], [ -0.01660479, 51.51857199 ], [ -0.02050458, 51.51697823 ], [ -0.02162257, 51.51654128 ], [ -0.02198512, 51.5168149 ], [ -0.02232217, 51.51717316 ], [ -0.0229023, 51.51806816 ], [ -0.0231217, 51.51846628 ], [ -0.02248057, 51.51861159 ], [ -0.02163343, 51.51910179 ], [ -0.0217933, 51.51923749 ], [ -0.022184, 51.51908799 ], [ -0.02284897, 51.51953087 ], [ -0.02260535, 51.51967486 ], [ -0.02260242, 51.51979171 ], [ -0.02124735, 51.51995715 ], [ -0.02134048, 51.52045536 ], [ -0.02073587, 51.52053341 ], [ -0.02043298, 51.52030666 ], [ -0.02029186, 51.52038175 ], [ -0.02046566, 51.5205683 ], [ -0.01967584, 51.52065805 ], [ -0.02007066, 51.52113093 ], [ -0.01899271, 51.52125957 ], [ -0.01872716, 51.5217317 ], [ -0.01808527, 51.52230052 ], [ -0.0177964, 51.52207658 ], [ -0.01736981, 51.52197193 ], [ -0.01678, 51.52189205 ], [ -0.01625093, 51.52173782 ], [ -0.0160704, 51.52200226 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 42, "LSOA11CD": "E01004243", "LSOA11NM": "Tower Hamlets 020A", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1789, "HHOLDRES": 1789, "COMESTRES": 0, "POPDEN": 153.400000, "HHOLDS": 614, "AVHHOLDSZ": 2.900000 }, "bbox": [ -0.00984877, 51.51142242, -0.00259956, 51.51519015 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00267487, 51.5122988 ], [ -0.00429845, 51.5120009 ], [ -0.00575649, 51.51170192 ], [ -0.00691201, 51.51149898 ], [ -0.00773787, 51.51142242 ], [ -0.00793699, 51.51166577 ], [ -0.00741933, 51.51163899 ], [ -0.0074251, 51.51183693 ], [ -0.00767078, 51.51281233 ], [ -0.00813556, 51.5127303 ], [ -0.00817099, 51.51257891 ], [ -0.00842212, 51.51243841 ], [ -0.00903728, 51.51261793 ], [ -0.00953532, 51.51292917 ], [ -0.00984877, 51.5136184 ], [ -0.00899819, 51.51377014 ], [ -0.00859415, 51.51378126 ], [ -0.00805068, 51.51401484 ], [ -0.00708413, 51.51420212 ], [ -0.00674508, 51.51420848 ], [ -0.00636933, 51.51412461 ], [ -0.00650583, 51.51441783 ], [ -0.00693797, 51.5146937 ], [ -0.00628038, 51.51481918 ], [ -0.00644962, 51.51519015 ], [ -0.00622742, 51.51517091 ], [ -0.00527305, 51.51491187 ], [ -0.00362084, 51.51446109 ], [ -0.00309272, 51.51335497 ], [ -0.00333361, 51.51331114 ], [ -0.00322234, 51.51305326 ], [ -0.00303029, 51.51306884 ], [ -0.00259956, 51.5123135 ], [ -0.00267487, 51.5122988 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 43, "LSOA11CD": "E01004250", "LSOA11NM": "Tower Hamlets 020D", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2342, "HHOLDRES": 2342, "COMESTRES": 0, "POPDEN": 234.400000, "HHOLDS": 866, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02095058, 51.51076026, -0.01385286, 51.51474456 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0166461, 51.51425868 ], [ -0.01619086, 51.51397833 ], [ -0.01603618, 51.51330837 ], [ -0.01562001, 51.51340032 ], [ -0.01543384, 51.51319189 ], [ -0.01500295, 51.51337785 ], [ -0.01484375, 51.5129907 ], [ -0.01507681, 51.51286048 ], [ -0.01485824, 51.5124248 ], [ -0.01496014, 51.51219812 ], [ -0.01389014, 51.51230632 ], [ -0.01385286, 51.51222616 ], [ -0.01459096, 51.51178672 ], [ -0.01436496, 51.51147538 ], [ -0.01450142, 51.51106057 ], [ -0.01738772, 51.51089786 ], [ -0.01972632, 51.51078786 ], [ -0.02095058, 51.51076026 ], [ -0.02085297, 51.51106177 ], [ -0.02001438, 51.51205875 ], [ -0.01997236, 51.51248759 ], [ -0.02007083, 51.51362347 ], [ -0.02007002, 51.51422359 ], [ -0.01993858, 51.51445041 ], [ -0.01956208, 51.51468889 ], [ -0.01949888, 51.51457745 ], [ -0.01899595, 51.51462411 ], [ -0.01881723, 51.51474456 ], [ -0.01842136, 51.51470084 ], [ -0.01801102, 51.51447345 ], [ -0.01788547, 51.51432425 ], [ -0.01776861, 51.51395482 ], [ -0.01724403, 51.51405847 ], [ -0.01707973, 51.51417458 ], [ -0.0166461, 51.51425868 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 44, "LSOA11CD": "E01004243", "LSOA11NM": "Tower Hamlets 020A", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1789, "HHOLDRES": 1789, "COMESTRES": 0, "POPDEN": 153.400000, "HHOLDS": 614, "AVHHOLDSZ": 2.900000 }, "bbox": [ -0.00726314, 51.5122988, 0.00413422, 51.51791835 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.00413422, 51.51458286 ], [ 0.00299081, 51.51433092 ], [ 0.00241746, 51.51411575 ], [ 0.0000259, 51.51282197 ], [ -0.00267487, 51.5122988 ], [ -0.00259956, 51.5123135 ], [ -0.00303029, 51.51306884 ], [ -0.00322234, 51.51305326 ], [ -0.00333361, 51.51331114 ], [ -0.00309272, 51.51335497 ], [ -0.00362084, 51.51446109 ], [ -0.00527305, 51.51491187 ], [ -0.00495175, 51.51533806 ], [ -0.00726314, 51.5159735 ], [ -0.00705046, 51.51617552 ], [ -0.00653626, 51.51636527 ], [ -0.00578086, 51.51701126 ], [ -0.00576125, 51.51683045 ], [ -0.00535349, 51.51653448 ], [ -0.0049755, 51.51650543 ], [ -0.00445691, 51.51670457 ], [ -0.00411093, 51.51707652 ], [ -0.00378228, 51.51756736 ], [ -0.00322982, 51.51781945 ], [ -0.00251109, 51.51791835 ], [ -0.00205952, 51.51784139 ], [ -0.00063988, 51.51711842 ], [ 0.000592, 51.51653156 ], [ 0.00173286, 51.51614971 ], [ 0.00268657, 51.51577371 ], [ 0.00319962, 51.51551765 ], [ 0.00391947, 51.51498573 ], [ 0.00413422, 51.51458286 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 45, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.01802342, 51.51313793, -0.00842602, 51.51955805 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01336912, 51.51732449 ], [ -0.0136671, 51.51726617 ], [ -0.01392508, 51.5173825 ], [ -0.01383471, 51.51762632 ], [ -0.01391442, 51.51771143 ], [ -0.01426597, 51.51758249 ], [ -0.01443144, 51.51742342 ], [ -0.01472422, 51.51734244 ], [ -0.01419703, 51.51565506 ], [ -0.0140387, 51.51498518 ], [ -0.01385167, 51.51510987 ], [ -0.01391838, 51.51530142 ], [ -0.011745, 51.51589409 ], [ -0.01146282, 51.51575441 ], [ -0.01112743, 51.51547423 ], [ -0.0106594, 51.51566884 ], [ -0.0106097, 51.515786 ], [ -0.01021513, 51.51581995 ], [ -0.00994777, 51.5159181 ], [ -0.00980101, 51.51581325 ], [ -0.00907433, 51.51599372 ], [ -0.00878871, 51.51526839 ], [ -0.0085618, 51.5151836 ], [ -0.00842602, 51.51480431 ], [ -0.00878537, 51.51472637 ], [ -0.00881039, 51.51454679 ], [ -0.01016232, 51.5141766 ], [ -0.00998802, 51.51387687 ], [ -0.0104346, 51.51386631 ], [ -0.0108831, 51.51378488 ], [ -0.01104031, 51.5141474 ], [ -0.01182875, 51.51397104 ], [ -0.01262635, 51.51385866 ], [ -0.01342551, 51.51371033 ], [ -0.01330026, 51.51327655 ], [ -0.01414222, 51.51313793 ], [ -0.01428099, 51.51350939 ], [ -0.01500295, 51.51337785 ], [ -0.01543384, 51.51319189 ], [ -0.01562001, 51.51340032 ], [ -0.01603618, 51.51330837 ], [ -0.01619086, 51.51397833 ], [ -0.0166461, 51.51425868 ], [ -0.01638738, 51.51449384 ], [ -0.01642702, 51.51472853 ], [ -0.01684623, 51.51469013 ], [ -0.01697603, 51.51524201 ], [ -0.01709145, 51.51548872 ], [ -0.01779858, 51.51537853 ], [ -0.01778054, 51.5155845 ], [ -0.01802342, 51.51583467 ], [ -0.01796998, 51.5159413 ], [ -0.01719948, 51.51611541 ], [ -0.01705974, 51.51639614 ], [ -0.01649039, 51.5163726 ], [ -0.01604675, 51.51607486 ], [ -0.0158953, 51.51624316 ], [ -0.0161886, 51.5177859 ], [ -0.01627849, 51.51803922 ], [ -0.01660479, 51.51857199 ], [ -0.0142345, 51.51955805 ], [ -0.01386066, 51.51915803 ], [ -0.01322155, 51.51939036 ], [ -0.01167524, 51.51948105 ], [ -0.01159556, 51.51899408 ], [ -0.01215303, 51.51889174 ], [ -0.0121111, 51.51852618 ], [ -0.01218168, 51.5184769 ], [ -0.01359869, 51.51838843 ], [ -0.01347446, 51.51816706 ], [ -0.01306857, 51.51804712 ], [ -0.01241381, 51.51800285 ], [ -0.01192978, 51.5177876 ], [ -0.01164931, 51.51776372 ], [ -0.01167027, 51.5174993 ], [ -0.01346681, 51.51739809 ], [ -0.01336912, 51.51732449 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 46, "LSOA11CD": "E01004243", "LSOA11NM": "Tower Hamlets 020A", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1789, "HHOLDRES": 1789, "COMESTRES": 0, "POPDEN": 153.400000, "HHOLDS": 614, "AVHHOLDSZ": 2.900000 }, "bbox": [ -0.01507681, 51.51106057, -0.00741933, 51.5141474 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00998802, 51.51387687 ], [ -0.00984877, 51.5136184 ], [ -0.00953532, 51.51292917 ], [ -0.00903728, 51.51261793 ], [ -0.00842212, 51.51243841 ], [ -0.00817099, 51.51257891 ], [ -0.00813556, 51.5127303 ], [ -0.00767078, 51.51281233 ], [ -0.0074251, 51.51183693 ], [ -0.00741933, 51.51163899 ], [ -0.00793699, 51.51166577 ], [ -0.00773787, 51.51142242 ], [ -0.0079982, 51.51141894 ], [ -0.01105226, 51.51122095 ], [ -0.01315003, 51.51113989 ], [ -0.01450142, 51.51106057 ], [ -0.01436496, 51.51147538 ], [ -0.01459096, 51.51178672 ], [ -0.01385286, 51.51222616 ], [ -0.01389014, 51.51230632 ], [ -0.01496014, 51.51219812 ], [ -0.01485824, 51.5124248 ], [ -0.01507681, 51.51286048 ], [ -0.01484375, 51.5129907 ], [ -0.01500295, 51.51337785 ], [ -0.01428099, 51.51350939 ], [ -0.01414222, 51.51313793 ], [ -0.01330026, 51.51327655 ], [ -0.01342551, 51.51371033 ], [ -0.01262635, 51.51385866 ], [ -0.01182875, 51.51397104 ], [ -0.01104031, 51.5141474 ], [ -0.0108831, 51.51378488 ], [ -0.0104346, 51.51386631 ], [ -0.00998802, 51.51387687 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 47, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.0142345, 51.51703116, -0.00769704, 51.52368677 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0081042, 51.51939243 ], [ -0.00938916, 51.51912324 ], [ -0.0100991, 51.51908516 ], [ -0.00952747, 51.51764588 ], [ -0.00982231, 51.51767803 ], [ -0.01023141, 51.51757809 ], [ -0.01019656, 51.51726823 ], [ -0.0122456, 51.51716566 ], [ -0.01222293, 51.51706996 ], [ -0.01284274, 51.51716059 ], [ -0.01295705, 51.51703116 ], [ -0.01336912, 51.51732449 ], [ -0.01346681, 51.51739809 ], [ -0.01167027, 51.5174993 ], [ -0.01164931, 51.51776372 ], [ -0.01192978, 51.5177876 ], [ -0.01241381, 51.51800285 ], [ -0.01306857, 51.51804712 ], [ -0.01347446, 51.51816706 ], [ -0.01359869, 51.51838843 ], [ -0.01218168, 51.5184769 ], [ -0.0121111, 51.51852618 ], [ -0.01215303, 51.51889174 ], [ -0.01159556, 51.51899408 ], [ -0.01167524, 51.51948105 ], [ -0.01322155, 51.51939036 ], [ -0.01386066, 51.51915803 ], [ -0.0142345, 51.51955805 ], [ -0.01383182, 51.51973151 ], [ -0.0126858, 51.52023207 ], [ -0.01186525, 51.52051704 ], [ -0.01133814, 51.5208081 ], [ -0.01107946, 51.52103809 ], [ -0.0101891, 51.52162199 ], [ -0.00905945, 51.52232098 ], [ -0.00851127, 51.52296984 ], [ -0.00809977, 51.52368677 ], [ -0.00805226, 51.52330981 ], [ -0.00769704, 51.52281985 ], [ -0.00834048, 51.52174292 ], [ -0.00869244, 51.52123392 ], [ -0.00898888, 51.52069601 ], [ -0.00901572, 51.52053502 ], [ -0.00890026, 51.51983612 ], [ -0.00882823, 51.51973218 ], [ -0.0081042, 51.51939243 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 48, "LSOA11CD": "E01004243", "LSOA11NM": "Tower Hamlets 020A", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1789, "HHOLDRES": 1789, "COMESTRES": 0, "POPDEN": 153.400000, "HHOLDS": 614, "AVHHOLDSZ": 2.900000 }, "bbox": [ -0.01472422, 51.5136184, -0.00495175, 51.51939243 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00578086, 51.51701126 ], [ -0.00653626, 51.51636527 ], [ -0.00705046, 51.51617552 ], [ -0.00726314, 51.5159735 ], [ -0.00495175, 51.51533806 ], [ -0.00527305, 51.51491187 ], [ -0.00622742, 51.51517091 ], [ -0.00644962, 51.51519015 ], [ -0.00628038, 51.51481918 ], [ -0.00693797, 51.5146937 ], [ -0.00650583, 51.51441783 ], [ -0.00636933, 51.51412461 ], [ -0.00674508, 51.51420848 ], [ -0.00708413, 51.51420212 ], [ -0.00805068, 51.51401484 ], [ -0.00859415, 51.51378126 ], [ -0.00899819, 51.51377014 ], [ -0.00984877, 51.5136184 ], [ -0.00998802, 51.51387687 ], [ -0.01016232, 51.5141766 ], [ -0.00881039, 51.51454679 ], [ -0.00878537, 51.51472637 ], [ -0.00842602, 51.51480431 ], [ -0.0085618, 51.5151836 ], [ -0.00878871, 51.51526839 ], [ -0.00907433, 51.51599372 ], [ -0.00980101, 51.51581325 ], [ -0.00994777, 51.5159181 ], [ -0.01021513, 51.51581995 ], [ -0.0106097, 51.515786 ], [ -0.0106594, 51.51566884 ], [ -0.01112743, 51.51547423 ], [ -0.01146282, 51.51575441 ], [ -0.011745, 51.51589409 ], [ -0.01391838, 51.51530142 ], [ -0.01385167, 51.51510987 ], [ -0.0140387, 51.51498518 ], [ -0.01419703, 51.51565506 ], [ -0.01472422, 51.51734244 ], [ -0.01443144, 51.51742342 ], [ -0.01426597, 51.51758249 ], [ -0.01391442, 51.51771143 ], [ -0.01383471, 51.51762632 ], [ -0.01392508, 51.5173825 ], [ -0.0136671, 51.51726617 ], [ -0.01336912, 51.51732449 ], [ -0.01295705, 51.51703116 ], [ -0.01284274, 51.51716059 ], [ -0.01222293, 51.51706996 ], [ -0.0122456, 51.51716566 ], [ -0.01019656, 51.51726823 ], [ -0.01023141, 51.51757809 ], [ -0.00982231, 51.51767803 ], [ -0.00952747, 51.51764588 ], [ -0.0100991, 51.51908516 ], [ -0.00938916, 51.51912324 ], [ -0.0081042, 51.51939243 ], [ -0.00717108, 51.51895622 ], [ -0.00679248, 51.51869335 ], [ -0.00635614, 51.5182464 ], [ -0.00600784, 51.51776442 ], [ -0.00579888, 51.51737137 ], [ -0.00578086, 51.51701126 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 49, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02162257, 51.51395482, -0.0158953, 51.51857199 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0166461, 51.51425868 ], [ -0.01707973, 51.51417458 ], [ -0.01724403, 51.51405847 ], [ -0.01776861, 51.51395482 ], [ -0.01788547, 51.51432425 ], [ -0.01801102, 51.51447345 ], [ -0.01842136, 51.51470084 ], [ -0.01881723, 51.51474456 ], [ -0.01899595, 51.51462411 ], [ -0.01949888, 51.51457745 ], [ -0.01956208, 51.51468889 ], [ -0.01989283, 51.51521445 ], [ -0.02056123, 51.51578276 ], [ -0.0214611, 51.51640029 ], [ -0.02162257, 51.51654128 ], [ -0.02050458, 51.51697823 ], [ -0.01660479, 51.51857199 ], [ -0.01627849, 51.51803922 ], [ -0.0161886, 51.5177859 ], [ -0.0158953, 51.51624316 ], [ -0.01604675, 51.51607486 ], [ -0.01649039, 51.5163726 ], [ -0.01705974, 51.51639614 ], [ -0.01719948, 51.51611541 ], [ -0.01796998, 51.5159413 ], [ -0.01802342, 51.51583467 ], [ -0.01778054, 51.5155845 ], [ -0.01779858, 51.51537853 ], [ -0.01709145, 51.51548872 ], [ -0.01697603, 51.51524201 ], [ -0.01684623, 51.51469013 ], [ -0.01642702, 51.51472853 ], [ -0.01638738, 51.51449384 ], [ -0.0166461, 51.51425868 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 50, "LSOA11CD": "E01004254", "LSOA11NM": "Tower Hamlets 023B", "MSOA11CD": "E02000886", "MSOA11NM": "Tower Hamlets 023", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2120, "HHOLDRES": 2120, "COMESTRES": 0, "POPDEN": 124.300000, "HHOLDS": 1046, "AVHHOLDSZ": 2.000000 }, "bbox": [ -0.03552861, 51.512322, -0.0282341, 51.51655219 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0282341, 51.51428336 ], [ -0.02887932, 51.51418918 ], [ -0.02914546, 51.51409359 ], [ -0.02931224, 51.51378459 ], [ -0.02906849, 51.51299711 ], [ -0.02998003, 51.5127401 ], [ -0.03022568, 51.51301208 ], [ -0.03079133, 51.51277571 ], [ -0.03164527, 51.512322 ], [ -0.03188883, 51.51235798 ], [ -0.03206753, 51.51255883 ], [ -0.03277802, 51.5131283 ], [ -0.03236624, 51.51331924 ], [ -0.03312053, 51.51387015 ], [ -0.03269804, 51.51398994 ], [ -0.03335382, 51.51443176 ], [ -0.03372648, 51.51419637 ], [ -0.03552861, 51.51403992 ], [ -0.03430697, 51.51538022 ], [ -0.03408556, 51.51571023 ], [ -0.03384028, 51.51621815 ], [ -0.03334034, 51.51655219 ], [ -0.03308705, 51.51597015 ], [ -0.03071767, 51.51603718 ], [ -0.02928086, 51.51626611 ], [ -0.0282341, 51.51428336 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 51, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02931224, 51.51006267, -0.02056123, 51.51654128 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02542721, 51.51047246 ], [ -0.0265358, 51.51044602 ], [ -0.02621938, 51.51023255 ], [ -0.0264105, 51.51006267 ], [ -0.02752624, 51.51097341 ], [ -0.02785213, 51.51079749 ], [ -0.02847466, 51.51129642 ], [ -0.02845949, 51.51164311 ], [ -0.0285618, 51.51171049 ], [ -0.02822524, 51.51175687 ], [ -0.02811823, 51.51189896 ], [ -0.02713461, 51.5116486 ], [ -0.02712024, 51.51198108 ], [ -0.02745424, 51.51225649 ], [ -0.02753094, 51.51248261 ], [ -0.02789176, 51.51247069 ], [ -0.02798341, 51.51213133 ], [ -0.02829791, 51.51226952 ], [ -0.02875664, 51.51206002 ], [ -0.02859516, 51.51247592 ], [ -0.02888346, 51.512941 ], [ -0.02906849, 51.51299711 ], [ -0.02931224, 51.51378459 ], [ -0.02914546, 51.51409359 ], [ -0.02887932, 51.51418918 ], [ -0.0282341, 51.51428336 ], [ -0.02803005, 51.51391946 ], [ -0.02573055, 51.51485142 ], [ -0.02439177, 51.51541735 ], [ -0.02287686, 51.51601428 ], [ -0.02162257, 51.51654128 ], [ -0.0214611, 51.51640029 ], [ -0.02056123, 51.51578276 ], [ -0.0210548, 51.51561725 ], [ -0.02214617, 51.51537489 ], [ -0.022643, 51.5150643 ], [ -0.02292201, 51.5146793 ], [ -0.02286547, 51.51417811 ], [ -0.02332383, 51.51400061 ], [ -0.02339049, 51.51372712 ], [ -0.02136457, 51.51372572 ], [ -0.02113606, 51.51363782 ], [ -0.02124305, 51.51338339 ], [ -0.02202537, 51.51322396 ], [ -0.02467991, 51.5132129 ], [ -0.02464037, 51.51264945 ], [ -0.02488733, 51.51270349 ], [ -0.02490491, 51.512873 ], [ -0.02524044, 51.512758 ], [ -0.02556966, 51.51276451 ], [ -0.02575746, 51.51264369 ], [ -0.02584743, 51.51234174 ], [ -0.02550926, 51.51222994 ], [ -0.02521598, 51.51259775 ], [ -0.02480907, 51.51236272 ], [ -0.0247626, 51.5121407 ], [ -0.02530443, 51.51207641 ], [ -0.02511898, 51.51176525 ], [ -0.02489067, 51.51161125 ], [ -0.02489744, 51.51132288 ], [ -0.02525656, 51.51141914 ], [ -0.02557378, 51.51141549 ], [ -0.02542721, 51.51047246 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 52, "LSOA11CD": "E01004250", "LSOA11NM": "Tower Hamlets 020D", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2342, "HHOLDRES": 2342, "COMESTRES": 0, "POPDEN": 234.400000, "HHOLDS": 866, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02584743, 51.50957234, -0.01956208, 51.51578276 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02095058, 51.51076026 ], [ -0.02104823, 51.51075467 ], [ -0.02290297, 51.51102242 ], [ -0.02304634, 51.51042016 ], [ -0.02320326, 51.51014997 ], [ -0.0234361, 51.51019243 ], [ -0.02369428, 51.50958599 ], [ -0.02386246, 51.50957234 ], [ -0.02438689, 51.5098587 ], [ -0.02484951, 51.50992121 ], [ -0.02497393, 51.5099993 ], [ -0.0254716, 51.51007133 ], [ -0.02542721, 51.51047246 ], [ -0.02557378, 51.51141549 ], [ -0.02525656, 51.51141914 ], [ -0.02489744, 51.51132288 ], [ -0.02489067, 51.51161125 ], [ -0.02511898, 51.51176525 ], [ -0.02530443, 51.51207641 ], [ -0.0247626, 51.5121407 ], [ -0.02480907, 51.51236272 ], [ -0.02521598, 51.51259775 ], [ -0.02550926, 51.51222994 ], [ -0.02584743, 51.51234174 ], [ -0.02575746, 51.51264369 ], [ -0.02556966, 51.51276451 ], [ -0.02524044, 51.512758 ], [ -0.02490491, 51.512873 ], [ -0.02488733, 51.51270349 ], [ -0.02464037, 51.51264945 ], [ -0.02467991, 51.5132129 ], [ -0.02202537, 51.51322396 ], [ -0.02124305, 51.51338339 ], [ -0.02113606, 51.51363782 ], [ -0.02136457, 51.51372572 ], [ -0.02339049, 51.51372712 ], [ -0.02332383, 51.51400061 ], [ -0.02286547, 51.51417811 ], [ -0.02292201, 51.5146793 ], [ -0.022643, 51.5150643 ], [ -0.02214617, 51.51537489 ], [ -0.0210548, 51.51561725 ], [ -0.02056123, 51.51578276 ], [ -0.01989283, 51.51521445 ], [ -0.01956208, 51.51468889 ], [ -0.01993858, 51.51445041 ], [ -0.02007002, 51.51422359 ], [ -0.02007083, 51.51362347 ], [ -0.01997236, 51.51248759 ], [ -0.02001438, 51.51205875 ], [ -0.02085297, 51.51106177 ], [ -0.02095058, 51.51076026 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 53, "LSOA11CD": "E01004258", "LSOA11NM": "Tower Hamlets 023D", "MSOA11CD": "E02000886", "MSOA11NM": "Tower Hamlets 023", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1506, "HHOLDRES": 1506, "COMESTRES": 0, "POPDEN": 154.500000, "HHOLDS": 713, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.03886167, 51.50815632, -0.02712024, 51.51443176 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02906849, 51.51299711 ], [ -0.02888346, 51.512941 ], [ -0.02859516, 51.51247592 ], [ -0.02875664, 51.51206002 ], [ -0.02829791, 51.51226952 ], [ -0.02798341, 51.51213133 ], [ -0.02789176, 51.51247069 ], [ -0.02753094, 51.51248261 ], [ -0.02745424, 51.51225649 ], [ -0.02712024, 51.51198108 ], [ -0.02713461, 51.5116486 ], [ -0.02811823, 51.51189896 ], [ -0.02822524, 51.51175687 ], [ -0.0285618, 51.51171049 ], [ -0.02917946, 51.5117616 ], [ -0.02898078, 51.51194943 ], [ -0.02966042, 51.51223063 ], [ -0.0297619, 51.51154889 ], [ -0.02984399, 51.51131645 ], [ -0.03023588, 51.51091835 ], [ -0.03048798, 51.5111651 ], [ -0.03123875, 51.51096953 ], [ -0.03180755, 51.51129926 ], [ -0.03219706, 51.51136503 ], [ -0.03270215, 51.51084586 ], [ -0.03302058, 51.51061313 ], [ -0.03350553, 51.51046898 ], [ -0.03324708, 51.51010711 ], [ -0.03356077, 51.50994116 ], [ -0.03405465, 51.50999792 ], [ -0.03432435, 51.50907242 ], [ -0.03499254, 51.50922658 ], [ -0.03644368, 51.50949806 ], [ -0.0363236, 51.50924873 ], [ -0.03641272, 51.50876547 ], [ -0.03666766, 51.50815632 ], [ -0.03780354, 51.50843184 ], [ -0.03886167, 51.50851993 ], [ -0.03653939, 51.51013967 ], [ -0.03564815, 51.51079866 ], [ -0.03487179, 51.51127857 ], [ -0.03539569, 51.51145358 ], [ -0.03622299, 51.51159052 ], [ -0.03677069, 51.5116105 ], [ -0.03661262, 51.51214448 ], [ -0.0364436, 51.51251439 ], [ -0.03625405, 51.51308834 ], [ -0.03603881, 51.51342239 ], [ -0.03552861, 51.51403992 ], [ -0.03372648, 51.51419637 ], [ -0.03335382, 51.51443176 ], [ -0.03269804, 51.51398994 ], [ -0.03312053, 51.51387015 ], [ -0.03236624, 51.51331924 ], [ -0.03277802, 51.5131283 ], [ -0.03206753, 51.51255883 ], [ -0.03188883, 51.51235798 ], [ -0.03164527, 51.512322 ], [ -0.03079133, 51.51277571 ], [ -0.03022568, 51.51301208 ], [ -0.02998003, 51.5127401 ], [ -0.02906849, 51.51299711 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 54, "LSOA11CD": "E01004256", "LSOA11NM": "Tower Hamlets 024C", "MSOA11CD": "E02000887", "MSOA11NM": "Tower Hamlets 024", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1729, "HHOLDRES": 1729, "COMESTRES": 0, "POPDEN": 120.700000, "HHOLDS": 611, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.03042343, 51.50776305, -0.02438689, 51.51223063 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0285618, 51.51171049 ], [ -0.02845949, 51.51164311 ], [ -0.02847466, 51.51129642 ], [ -0.02785213, 51.51079749 ], [ -0.02752624, 51.51097341 ], [ -0.0264105, 51.51006267 ], [ -0.02621938, 51.51023255 ], [ -0.0265358, 51.51044602 ], [ -0.02542721, 51.51047246 ], [ -0.0254716, 51.51007133 ], [ -0.02497393, 51.5099993 ], [ -0.02484951, 51.50992121 ], [ -0.02438689, 51.5098587 ], [ -0.02446848, 51.50948997 ], [ -0.02504977, 51.50953616 ], [ -0.02515698, 51.50945876 ], [ -0.02551541, 51.50972385 ], [ -0.02617673, 51.5094069 ], [ -0.02665769, 51.5089489 ], [ -0.02689131, 51.50866998 ], [ -0.02717231, 51.50816999 ], [ -0.02727255, 51.50785102 ], [ -0.02761165, 51.50786193 ], [ -0.02909303, 51.50776305 ], [ -0.02923373, 51.50781565 ], [ -0.02930428, 51.50793394 ], [ -0.02912118, 51.50813384 ], [ -0.02895168, 51.50878383 ], [ -0.02961957, 51.50888865 ], [ -0.02986815, 51.50908664 ], [ -0.02995616, 51.50938488 ], [ -0.03032056, 51.50995755 ], [ -0.0304222, 51.510274 ], [ -0.03042343, 51.51057978 ], [ -0.03023588, 51.51091835 ], [ -0.02984399, 51.51131645 ], [ -0.0297619, 51.51154889 ], [ -0.02966042, 51.51223063 ], [ -0.02898078, 51.51194943 ], [ -0.02917946, 51.5117616 ], [ -0.0285618, 51.51171049 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 55, "LSOA11CD": "E01004256", "LSOA11NM": "Tower Hamlets 024C", "MSOA11CD": "E02000887", "MSOA11NM": "Tower Hamlets 024", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1729, "HHOLDRES": 1729, "COMESTRES": 0, "POPDEN": 120.700000, "HHOLDS": 611, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.02515698, 51.50734428, -0.01336775, 51.51102242 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02104823, 51.51075467 ], [ -0.02112158, 51.51042046 ], [ -0.02069224, 51.51042401 ], [ -0.01985401, 51.51025637 ], [ -0.01971457, 51.51042801 ], [ -0.0194451, 51.51051797 ], [ -0.01910066, 51.51042547 ], [ -0.01908689, 51.51017037 ], [ -0.01838052, 51.51013193 ], [ -0.01854563, 51.50964226 ], [ -0.01893989, 51.50952303 ], [ -0.01924077, 51.50956408 ], [ -0.0194463, 51.50914489 ], [ -0.01860211, 51.50900473 ], [ -0.01735355, 51.5088847 ], [ -0.01608551, 51.50888124 ], [ -0.01409901, 51.50882963 ], [ -0.01388875, 51.50869955 ], [ -0.01395181, 51.50840873 ], [ -0.01385696, 51.50814622 ], [ -0.01336775, 51.50735215 ], [ -0.01424917, 51.50734428 ], [ -0.01605046, 51.5074283 ], [ -0.01850496, 51.5076942 ], [ -0.01924691, 51.50784416 ], [ -0.0205398, 51.50827108 ], [ -0.0217621, 51.50845711 ], [ -0.02293536, 51.50871394 ], [ -0.02416847, 51.5089209 ], [ -0.02473441, 51.50914289 ], [ -0.02515698, 51.50945876 ], [ -0.02504977, 51.50953616 ], [ -0.02446848, 51.50948997 ], [ -0.02438689, 51.5098587 ], [ -0.02386246, 51.50957234 ], [ -0.02369428, 51.50958599 ], [ -0.0234361, 51.51019243 ], [ -0.02320326, 51.51014997 ], [ -0.02304634, 51.51042016 ], [ -0.02290297, 51.51102242 ], [ -0.02104823, 51.51075467 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 56, "LSOA11CD": "E01004244", "LSOA11NM": "Tower Hamlets 020B", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1885, "HHOLDRES": 1788, "COMESTRES": 97, "POPDEN": 137.100000, "HHOLDS": 686, "AVHHOLDSZ": 2.600000 }, "bbox": [ -0.02112158, 51.50735215, -0.01174816, 51.51113989 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01205159, 51.50752934 ], [ -0.01246922, 51.50741135 ], [ -0.01336775, 51.50735215 ], [ -0.01385696, 51.50814622 ], [ -0.01395181, 51.50840873 ], [ -0.01388875, 51.50869955 ], [ -0.01409901, 51.50882963 ], [ -0.01608551, 51.50888124 ], [ -0.01735355, 51.5088847 ], [ -0.01860211, 51.50900473 ], [ -0.0194463, 51.50914489 ], [ -0.01924077, 51.50956408 ], [ -0.01893989, 51.50952303 ], [ -0.01854563, 51.50964226 ], [ -0.01838052, 51.51013193 ], [ -0.01908689, 51.51017037 ], [ -0.01910066, 51.51042547 ], [ -0.0194451, 51.51051797 ], [ -0.01971457, 51.51042801 ], [ -0.01985401, 51.51025637 ], [ -0.02069224, 51.51042401 ], [ -0.02112158, 51.51042046 ], [ -0.02104823, 51.51075467 ], [ -0.02095058, 51.51076026 ], [ -0.01972632, 51.51078786 ], [ -0.01738772, 51.51089786 ], [ -0.01450142, 51.51106057 ], [ -0.01315003, 51.51113989 ], [ -0.01290998, 51.51013593 ], [ -0.01259208, 51.50930713 ], [ -0.01235254, 51.50889206 ], [ -0.01186234, 51.50823515 ], [ -0.01174816, 51.50789923 ], [ -0.01185167, 51.50767321 ], [ -0.01205159, 51.50752934 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 57, "LSOA11CD": "E01004258", "LSOA11NM": "Tower Hamlets 023D", "MSOA11CD": "E02000886", "MSOA11NM": "Tower Hamlets 023", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1506, "HHOLDRES": 1506, "COMESTRES": 0, "POPDEN": 154.500000, "HHOLDS": 713, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.03666766, 51.50649205, -0.02895168, 51.51136503 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03023588, 51.51091835 ], [ -0.03042343, 51.51057978 ], [ -0.0304222, 51.510274 ], [ -0.03032056, 51.50995755 ], [ -0.02995616, 51.50938488 ], [ -0.02986815, 51.50908664 ], [ -0.02961957, 51.50888865 ], [ -0.02895168, 51.50878383 ], [ -0.02912118, 51.50813384 ], [ -0.02930428, 51.50793394 ], [ -0.02923373, 51.50781565 ], [ -0.02953343, 51.50784702 ], [ -0.03039267, 51.50717913 ], [ -0.03163278, 51.50649205 ], [ -0.03218395, 51.50682701 ], [ -0.03456144, 51.50758602 ], [ -0.03561424, 51.50790198 ], [ -0.03666766, 51.50815632 ], [ -0.03641272, 51.50876547 ], [ -0.0363236, 51.50924873 ], [ -0.03644368, 51.50949806 ], [ -0.03499254, 51.50922658 ], [ -0.03432435, 51.50907242 ], [ -0.03405465, 51.50999792 ], [ -0.03356077, 51.50994116 ], [ -0.03324708, 51.51010711 ], [ -0.03350553, 51.51046898 ], [ -0.03302058, 51.51061313 ], [ -0.03270215, 51.51084586 ], [ -0.03219706, 51.51136503 ], [ -0.03180755, 51.51129926 ], [ -0.03123875, 51.51096953 ], [ -0.03048798, 51.5111651 ], [ -0.03023588, 51.51091835 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 58, "LSOA11CD": "E01004266", "LSOA11NM": "Tower Hamlets 007D", "MSOA11CD": "E02000870", "MSOA11NM": "Tower Hamlets 007", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1545, "HHOLDRES": 1545, "COMESTRES": 0, "POPDEN": 188.200000, "HHOLDS": 583, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.05583716, 51.52503776, -0.04612776, 51.52984449 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04927631, 51.5288028 ], [ -0.04970307, 51.52867394 ], [ -0.05003403, 51.52871153 ], [ -0.05020701, 51.52844394 ], [ -0.05009401, 51.52824542 ], [ -0.04899139, 51.52854728 ], [ -0.04895063, 51.52841352 ], [ -0.04939223, 51.52804079 ], [ -0.04917374, 51.52776369 ], [ -0.0488365, 51.52786562 ], [ -0.04869893, 51.5277551 ], [ -0.04874999, 51.5275588 ], [ -0.04801189, 51.52705493 ], [ -0.04736972, 51.52726149 ], [ -0.04693998, 51.52639558 ], [ -0.04630032, 51.52651981 ], [ -0.04612776, 51.52640655 ], [ -0.04629064, 51.52637931 ], [ -0.04615565, 51.52613402 ], [ -0.04704372, 51.52599263 ], [ -0.04745248, 51.52587354 ], [ -0.04914712, 51.52503776 ], [ -0.04991255, 51.52574094 ], [ -0.0504415, 51.52649895 ], [ -0.05113639, 51.52784521 ], [ -0.0533304, 51.52752421 ], [ -0.05529357, 51.52726517 ], [ -0.05537408, 51.52748672 ], [ -0.05550651, 51.5278468 ], [ -0.05556775, 51.52843964 ], [ -0.05580286, 51.5291731 ], [ -0.05583716, 51.52926457 ], [ -0.05383392, 51.52984449 ], [ -0.05347024, 51.52936622 ], [ -0.0533836, 51.5294194 ], [ -0.05293864, 51.52930781 ], [ -0.05259806, 51.52933546 ], [ -0.05207919, 51.52893608 ], [ -0.05145602, 51.52867393 ], [ -0.05112047, 51.52890494 ], [ -0.05122341, 51.52909459 ], [ -0.05107438, 51.52925584 ], [ -0.05070389, 51.5293177 ], [ -0.0504554, 51.52881018 ], [ -0.04971929, 51.52900621 ], [ -0.04946257, 51.52899044 ], [ -0.04927631, 51.5288028 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 59, "LSOA11CD": "E01004266", "LSOA11NM": "Tower Hamlets 007D", "MSOA11CD": "E02000870", "MSOA11NM": "Tower Hamlets 007", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1545, "HHOLDRES": 1545, "COMESTRES": 0, "POPDEN": 188.200000, "HHOLDS": 583, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.05020701, 51.52639558, -0.04304367, 51.52956846 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04352484, 51.52684018 ], [ -0.04612776, 51.52640655 ], [ -0.04630032, 51.52651981 ], [ -0.04693998, 51.52639558 ], [ -0.04736972, 51.52726149 ], [ -0.04801189, 51.52705493 ], [ -0.04874999, 51.5275588 ], [ -0.04869893, 51.5277551 ], [ -0.0488365, 51.52786562 ], [ -0.04917374, 51.52776369 ], [ -0.04939223, 51.52804079 ], [ -0.04895063, 51.52841352 ], [ -0.04899139, 51.52854728 ], [ -0.05009401, 51.52824542 ], [ -0.05020701, 51.52844394 ], [ -0.05003403, 51.52871153 ], [ -0.04970307, 51.52867394 ], [ -0.04927631, 51.5288028 ], [ -0.04913902, 51.5287694 ], [ -0.0485704, 51.52916236 ], [ -0.04781007, 51.52885783 ], [ -0.04737783, 51.52896581 ], [ -0.0472181, 51.52885652 ], [ -0.04698366, 51.52849587 ], [ -0.0467489, 51.52845682 ], [ -0.04640322, 51.5285836 ], [ -0.0466782, 51.52914301 ], [ -0.04630344, 51.52911519 ], [ -0.04619441, 51.52897328 ], [ -0.04528505, 51.52916729 ], [ -0.04527629, 51.52938281 ], [ -0.04486179, 51.52956846 ], [ -0.04376308, 51.52875962 ], [ -0.04341899, 51.52841954 ], [ -0.04324563, 51.5278695 ], [ -0.04335376, 51.52784374 ], [ -0.04304367, 51.52752601 ], [ -0.04366484, 51.52722246 ], [ -0.04352484, 51.52684018 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 60, "LSOA11CD": "E01004264", "LSOA11NM": "Tower Hamlets 010C", "MSOA11CD": "E02000873", "MSOA11NM": "Tower Hamlets 010", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1537, "HHOLDRES": 1537, "COMESTRES": 0, "POPDEN": 252.800000, "HHOLDS": 457, "AVHHOLDSZ": 3.400000 }, "bbox": [ -0.04549099, 51.52111356, -0.03648225, 51.52694225 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03707324, 51.52418232 ], [ -0.03682406, 51.52381731 ], [ -0.03654731, 51.52317152 ], [ -0.03648225, 51.52191315 ], [ -0.0371849, 51.52197438 ], [ -0.03733302, 51.52211392 ], [ -0.03794511, 51.5224737 ], [ -0.03881189, 51.52228364 ], [ -0.03937828, 51.52220467 ], [ -0.03931204, 51.52206867 ], [ -0.03977763, 51.52196854 ], [ -0.04058461, 51.52226588 ], [ -0.04123576, 51.52180952 ], [ -0.04103536, 51.52154891 ], [ -0.04102975, 51.52119397 ], [ -0.04131969, 51.5211685 ], [ -0.04167475, 51.52124916 ], [ -0.0419486, 51.52153148 ], [ -0.04397702, 51.52111356 ], [ -0.04431301, 51.52147273 ], [ -0.04418007, 51.52154188 ], [ -0.04407182, 51.52198056 ], [ -0.04420171, 51.5220405 ], [ -0.04427036, 51.52242602 ], [ -0.04452883, 51.5224492 ], [ -0.04480286, 51.52233021 ], [ -0.04543944, 51.5225869 ], [ -0.04549099, 51.52266869 ], [ -0.04526854, 51.52295439 ], [ -0.04488818, 51.52324153 ], [ -0.04459105, 51.5231785 ], [ -0.04429253, 51.52295723 ], [ -0.04398288, 51.52285709 ], [ -0.04355327, 51.52290713 ], [ -0.04313994, 51.5222385 ], [ -0.04247268, 51.52231931 ], [ -0.04232553, 51.52238879 ], [ -0.04151113, 51.52255505 ], [ -0.04101827, 51.52261876 ], [ -0.04160569, 51.52337497 ], [ -0.04115295, 51.5235113 ], [ -0.04138512, 51.52394069 ], [ -0.04232324, 51.52400554 ], [ -0.04192919, 51.52423469 ], [ -0.04236151, 51.52457464 ], [ -0.04263522, 51.52457921 ], [ -0.04280269, 51.52470791 ], [ -0.04317602, 51.52450136 ], [ -0.0432195, 51.52485525 ], [ -0.04254613, 51.52516347 ], [ -0.04214031, 51.52521259 ], [ -0.04171416, 51.52487858 ], [ -0.04125523, 51.52515869 ], [ -0.04108886, 51.52519876 ], [ -0.04095265, 51.52540175 ], [ -0.03974306, 51.52694225 ], [ -0.03941501, 51.52646702 ], [ -0.03874176, 51.52573719 ], [ -0.03811627, 51.52517521 ], [ -0.03707324, 51.52418232 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 61, "LSOA11CD": "E01004259", "LSOA11NM": "Tower Hamlets 007A", "MSOA11CD": "E02000870", "MSOA11NM": "Tower Hamlets 007", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1723, "HHOLDRES": 1694, "COMESTRES": 29, "POPDEN": 129.300000, "HHOLDS": 812, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.04712187, 51.52092136, -0.03974306, 51.52725139 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04397702, 51.52111356 ], [ -0.0449258, 51.52092136 ], [ -0.04564139, 51.52193938 ], [ -0.046207, 51.52181744 ], [ -0.04712187, 51.52274479 ], [ -0.04691734, 51.52308951 ], [ -0.0466864, 51.52286209 ], [ -0.04455764, 51.52345121 ], [ -0.04380794, 51.52378943 ], [ -0.04454242, 51.52442516 ], [ -0.04422259, 51.52455703 ], [ -0.04538513, 51.52565167 ], [ -0.04568958, 51.52598937 ], [ -0.04572278, 51.52621438 ], [ -0.04615565, 51.52613402 ], [ -0.04629064, 51.52637931 ], [ -0.04612776, 51.52640655 ], [ -0.04352484, 51.52684018 ], [ -0.04312644, 51.52690755 ], [ -0.04214217, 51.52699904 ], [ -0.03994505, 51.52725139 ], [ -0.03974306, 51.52694225 ], [ -0.04095265, 51.52540175 ], [ -0.04108886, 51.52519876 ], [ -0.04125523, 51.52515869 ], [ -0.04171416, 51.52487858 ], [ -0.04214031, 51.52521259 ], [ -0.04254613, 51.52516347 ], [ -0.0432195, 51.52485525 ], [ -0.04317602, 51.52450136 ], [ -0.04280269, 51.52470791 ], [ -0.04263522, 51.52457921 ], [ -0.04236151, 51.52457464 ], [ -0.04192919, 51.52423469 ], [ -0.04232324, 51.52400554 ], [ -0.04138512, 51.52394069 ], [ -0.04115295, 51.5235113 ], [ -0.04160569, 51.52337497 ], [ -0.04101827, 51.52261876 ], [ -0.04151113, 51.52255505 ], [ -0.04232553, 51.52238879 ], [ -0.04247268, 51.52231931 ], [ -0.04313994, 51.5222385 ], [ -0.04355327, 51.52290713 ], [ -0.04398288, 51.52285709 ], [ -0.04429253, 51.52295723 ], [ -0.04459105, 51.5231785 ], [ -0.04488818, 51.52324153 ], [ -0.04526854, 51.52295439 ], [ -0.04549099, 51.52266869 ], [ -0.04543944, 51.5225869 ], [ -0.04480286, 51.52233021 ], [ -0.04452883, 51.5224492 ], [ -0.04427036, 51.52242602 ], [ -0.04420171, 51.5220405 ], [ -0.04407182, 51.52198056 ], [ -0.04418007, 51.52154188 ], [ -0.04431301, 51.52147273 ], [ -0.04397702, 51.52111356 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 62, "LSOA11CD": "E01004259", "LSOA11NM": "Tower Hamlets 007A", "MSOA11CD": "E02000870", "MSOA11NM": "Tower Hamlets 007", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1723, "HHOLDRES": 1694, "COMESTRES": 29, "POPDEN": 129.300000, "HHOLDS": 812, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.04914712, 51.52274479, -0.04380794, 51.52621438 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04712187, 51.52274479 ], [ -0.04792224, 51.52365424 ], [ -0.04867538, 51.52458319 ], [ -0.04892247, 51.52483127 ], [ -0.04914712, 51.52503776 ], [ -0.04745248, 51.52587354 ], [ -0.04704372, 51.52599263 ], [ -0.04615565, 51.52613402 ], [ -0.04572278, 51.52621438 ], [ -0.04568958, 51.52598937 ], [ -0.04538513, 51.52565167 ], [ -0.04422259, 51.52455703 ], [ -0.04454242, 51.52442516 ], [ -0.04380794, 51.52378943 ], [ -0.04455764, 51.52345121 ], [ -0.0466864, 51.52286209 ], [ -0.04691734, 51.52308951 ], [ -0.04712187, 51.52274479 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 63, "LSOA11CD": "E01004284", "LSOA11NM": "Tower Hamlets 019A", "MSOA11CD": "E02000882", "MSOA11NM": "Tower Hamlets 019", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2302, "HHOLDRES": 2302, "COMESTRES": 0, "POPDEN": 120.600000, "HHOLDS": 884, "AVHHOLDSZ": 2.600000 }, "bbox": [ -0.0449258, 51.52009458, -0.03644733, 51.5224737 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03648225, 51.52191315 ], [ -0.03644733, 51.52141162 ], [ -0.03696169, 51.52141362 ], [ -0.0379267, 51.52130654 ], [ -0.03907459, 51.52111568 ], [ -0.04239373, 51.52042722 ], [ -0.04402305, 51.52009458 ], [ -0.0449258, 51.52092136 ], [ -0.04397702, 51.52111356 ], [ -0.0419486, 51.52153148 ], [ -0.04167475, 51.52124916 ], [ -0.04131969, 51.5211685 ], [ -0.04102975, 51.52119397 ], [ -0.04103536, 51.52154891 ], [ -0.04123576, 51.52180952 ], [ -0.04058461, 51.52226588 ], [ -0.03977763, 51.52196854 ], [ -0.03931204, 51.52206867 ], [ -0.03937828, 51.52220467 ], [ -0.03881189, 51.52228364 ], [ -0.03794511, 51.5224737 ], [ -0.03733302, 51.52211392 ], [ -0.0371849, 51.52197438 ], [ -0.03648225, 51.52191315 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 64, "LSOA11CD": "E01004201", "LSOA11NM": "Tower Hamlets 002D", "MSOA11CD": "E02000865", "MSOA11NM": "Tower Hamlets 002", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1556, "HHOLDRES": 1533, "COMESTRES": 23, "POPDEN": 119.900000, "HHOLDS": 619, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.05383392, 51.52867393, -0.04536604, 51.53138733 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04737783, 51.52896581 ], [ -0.04781007, 51.52885783 ], [ -0.0485704, 51.52916236 ], [ -0.04913902, 51.5287694 ], [ -0.04927631, 51.5288028 ], [ -0.04946257, 51.52899044 ], [ -0.04971929, 51.52900621 ], [ -0.0504554, 51.52881018 ], [ -0.05070389, 51.5293177 ], [ -0.05107438, 51.52925584 ], [ -0.05122341, 51.52909459 ], [ -0.05112047, 51.52890494 ], [ -0.05145602, 51.52867393 ], [ -0.05207919, 51.52893608 ], [ -0.05259806, 51.52933546 ], [ -0.05293864, 51.52930781 ], [ -0.0533836, 51.5294194 ], [ -0.05347024, 51.52936622 ], [ -0.05383392, 51.52984449 ], [ -0.05219541, 51.53027893 ], [ -0.05151024, 51.53047702 ], [ -0.05088991, 51.5306561 ], [ -0.05038601, 51.53072954 ], [ -0.04975042, 51.53075748 ], [ -0.0478985, 51.53100118 ], [ -0.04652046, 51.53112259 ], [ -0.04536604, 51.53138733 ], [ -0.04542071, 51.53120809 ], [ -0.0456534, 51.53094894 ], [ -0.04614148, 51.53085646 ], [ -0.04638177, 51.53051654 ], [ -0.04629477, 51.53044816 ], [ -0.04692614, 51.53032502 ], [ -0.04714517, 51.52992329 ], [ -0.04754601, 51.53012916 ], [ -0.04783902, 51.53006184 ], [ -0.04783168, 51.52985193 ], [ -0.04769153, 51.52969935 ], [ -0.04768707, 51.52946427 ], [ -0.04737783, 51.52896581 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 65, "LSOA11CD": "E01004237", "LSOA11NM": "Tower Hamlets 008C", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1158, "HHOLDRES": 1158, "COMESTRES": 0, "POPDEN": 177.300000, "HHOLDS": 506, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.02831343, 51.52070142, -0.01876345, 51.52787417 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01885339, 51.52460702 ], [ -0.01876345, 51.52446556 ], [ -0.01948644, 51.52448161 ], [ -0.02030389, 51.52449257 ], [ -0.02131431, 51.52440058 ], [ -0.02189757, 51.52426851 ], [ -0.02284554, 51.52391255 ], [ -0.02347385, 51.52353055 ], [ -0.02439352, 51.52273695 ], [ -0.02678893, 51.52104281 ], [ -0.02735932, 51.52070142 ], [ -0.02747734, 51.52072812 ], [ -0.02767836, 51.52078043 ], [ -0.0273096, 51.52127386 ], [ -0.02745407, 51.52160003 ], [ -0.02763473, 51.52175595 ], [ -0.02771809, 51.52216203 ], [ -0.0282071, 51.52252097 ], [ -0.02831343, 51.52272959 ], [ -0.02802106, 51.5228236 ], [ -0.02827224, 51.5233494 ], [ -0.02699408, 51.52357071 ], [ -0.02664877, 51.52388865 ], [ -0.02587635, 51.52408248 ], [ -0.02543327, 51.52399409 ], [ -0.02503616, 51.52417625 ], [ -0.02499839, 51.52438245 ], [ -0.02521917, 51.52461099 ], [ -0.02570585, 51.52469112 ], [ -0.02596382, 51.52460004 ], [ -0.02609278, 51.52472496 ], [ -0.02601734, 51.52482227 ], [ -0.02541658, 51.52504596 ], [ -0.02476927, 51.52522163 ], [ -0.02482364, 51.52542267 ], [ -0.02571985, 51.52697513 ], [ -0.02451992, 51.52723523 ], [ -0.02319645, 51.52748018 ], [ -0.02268094, 51.52760722 ], [ -0.02178707, 51.52777426 ], [ -0.02101231, 51.52787417 ], [ -0.02028532, 51.52683137 ], [ -0.02022701, 51.52684626 ], [ -0.01904809, 51.52504845 ], [ -0.01912275, 51.5250306 ], [ -0.01885339, 51.52460702 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 66, "LSOA11CD": "E01004229", "LSOA11NM": "Tower Hamlets 004C", "MSOA11CD": "E02000867", "MSOA11NM": "Tower Hamlets 004", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1484, "HHOLDRES": 1484, "COMESTRES": 0, "POPDEN": 142.400000, "HHOLDS": 551, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02881024, 51.52428642, -0.02476927, 51.52697513 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0279591, 51.52648972 ], [ -0.02688918, 51.52672166 ], [ -0.02571985, 51.52697513 ], [ -0.02482364, 51.52542267 ], [ -0.02476927, 51.52522163 ], [ -0.02541658, 51.52504596 ], [ -0.02601734, 51.52482227 ], [ -0.02609278, 51.52472496 ], [ -0.02657602, 51.52457088 ], [ -0.02784252, 51.52428642 ], [ -0.02881024, 51.52591241 ], [ -0.02870241, 51.52607247 ], [ -0.02782872, 51.5262736 ], [ -0.0279591, 51.52648972 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 67, "LSOA11CD": "E01004232", "LSOA11NM": "Tower Hamlets 003C", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1665, "HHOLDRES": 1631, "COMESTRES": 34, "POPDEN": 86.100000, "HHOLDS": 603, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.03490031, 51.52176773, -0.02499839, 51.52648972 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02609278, 51.52472496 ], [ -0.02596382, 51.52460004 ], [ -0.02570585, 51.52469112 ], [ -0.02521917, 51.52461099 ], [ -0.02499839, 51.52438245 ], [ -0.02503616, 51.52417625 ], [ -0.02543327, 51.52399409 ], [ -0.02587635, 51.52408248 ], [ -0.02664877, 51.52388865 ], [ -0.02699408, 51.52357071 ], [ -0.02827224, 51.5233494 ], [ -0.02946395, 51.52312663 ], [ -0.02979803, 51.52340203 ], [ -0.03002735, 51.52343287 ], [ -0.03024776, 51.52367037 ], [ -0.03072662, 51.52359748 ], [ -0.02993174, 51.52197442 ], [ -0.02994066, 51.52176773 ], [ -0.03051646, 51.52178639 ], [ -0.03062744, 51.52188718 ], [ -0.03150515, 51.52191141 ], [ -0.03123117, 51.52209819 ], [ -0.0314314, 51.52223949 ], [ -0.03097936, 51.5225691 ], [ -0.03133291, 51.52260867 ], [ -0.03169359, 51.52273076 ], [ -0.03187387, 51.52303963 ], [ -0.03224493, 51.52302062 ], [ -0.03242866, 51.522937 ], [ -0.03283792, 51.52296165 ], [ -0.03305952, 51.52306836 ], [ -0.03381485, 51.52296733 ], [ -0.03421606, 51.52305127 ], [ -0.03454229, 51.52437191 ], [ -0.03472299, 51.52452783 ], [ -0.03490031, 51.52494088 ], [ -0.03366534, 51.52525636 ], [ -0.02980691, 51.52611055 ], [ -0.0279591, 51.52648972 ], [ -0.02782872, 51.5262736 ], [ -0.02870241, 51.52607247 ], [ -0.02881024, 51.52591241 ], [ -0.02784252, 51.52428642 ], [ -0.02657602, 51.52457088 ], [ -0.02609278, 51.52472496 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 68, "LSOA11CD": "E01004284", "LSOA11NM": "Tower Hamlets 019A", "MSOA11CD": "E02000882", "MSOA11NM": "Tower Hamlets 019", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2302, "HHOLDRES": 2302, "COMESTRES": 0, "POPDEN": 120.600000, "HHOLDS": 884, "AVHHOLDSZ": 2.600000 }, "bbox": [ -0.03707324, 51.51738421, -0.0273096, 51.52494088 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02827224, 51.5233494 ], [ -0.02802106, 51.5228236 ], [ -0.02831343, 51.52272959 ], [ -0.0282071, 51.52252097 ], [ -0.02771809, 51.52216203 ], [ -0.02763473, 51.52175595 ], [ -0.02745407, 51.52160003 ], [ -0.0273096, 51.52127386 ], [ -0.02767836, 51.52078043 ], [ -0.02747734, 51.52072812 ], [ -0.02848118, 51.52000495 ], [ -0.02891777, 51.52041953 ], [ -0.02842359, 51.52055098 ], [ -0.02840107, 51.52078224 ], [ -0.02926548, 51.52104595 ], [ -0.03047862, 51.52132713 ], [ -0.0307461, 51.52108131 ], [ -0.03056604, 51.52083849 ], [ -0.03061481, 51.5205127 ], [ -0.03051237, 51.52038801 ], [ -0.03048717, 51.51997056 ], [ -0.03061823, 51.52000148 ], [ -0.03057211, 51.51942471 ], [ -0.03097559, 51.51932383 ], [ -0.03051712, 51.5185979 ], [ -0.03070924, 51.51848843 ], [ -0.03231701, 51.51738421 ], [ -0.03257967, 51.51739656 ], [ -0.03341902, 51.51765345 ], [ -0.03392981, 51.51784187 ], [ -0.0348728, 51.51837026 ], [ -0.03539955, 51.51852297 ], [ -0.03565041, 51.51839714 ], [ -0.03612635, 51.51882081 ], [ -0.03624726, 51.51913084 ], [ -0.03635615, 51.52011766 ], [ -0.03644733, 51.52141162 ], [ -0.03648225, 51.52191315 ], [ -0.03654731, 51.52317152 ], [ -0.03682406, 51.52381731 ], [ -0.03707324, 51.52418232 ], [ -0.03573774, 51.52469026 ], [ -0.03490031, 51.52494088 ], [ -0.03472299, 51.52452783 ], [ -0.03454229, 51.52437191 ], [ -0.03421606, 51.52305127 ], [ -0.03381485, 51.52296733 ], [ -0.03305952, 51.52306836 ], [ -0.03283792, 51.52296165 ], [ -0.03242866, 51.522937 ], [ -0.03224493, 51.52302062 ], [ -0.03187387, 51.52303963 ], [ -0.03169359, 51.52273076 ], [ -0.03133291, 51.52260867 ], [ -0.03097936, 51.5225691 ], [ -0.0314314, 51.52223949 ], [ -0.03123117, 51.52209819 ], [ -0.03150515, 51.52191141 ], [ -0.03062744, 51.52188718 ], [ -0.03051646, 51.52178639 ], [ -0.02994066, 51.52176773 ], [ -0.02993174, 51.52197442 ], [ -0.03072662, 51.52359748 ], [ -0.03024776, 51.52367037 ], [ -0.03002735, 51.52343287 ], [ -0.02979803, 51.52340203 ], [ -0.02946395, 51.52312663 ], [ -0.02827224, 51.5233494 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 69, "LSOA11CD": "E01004270", "LSOA11NM": "Tower Hamlets 014B", "MSOA11CD": "E02000877", "MSOA11NM": "Tower Hamlets 014", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2236, "HHOLDRES": 2236, "COMESTRES": 0, "POPDEN": 76.200000, "HHOLDS": 745, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.03097559, 51.51721171, -0.02474955, 51.52132713 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02747734, 51.52072812 ], [ -0.02735932, 51.52070142 ], [ -0.02683627, 51.52057289 ], [ -0.02586026, 51.52010092 ], [ -0.02474955, 51.51971634 ], [ -0.02500321, 51.51945347 ], [ -0.02526668, 51.51899897 ], [ -0.02587359, 51.51916317 ], [ -0.02620965, 51.5193158 ], [ -0.02697506, 51.51937693 ], [ -0.02709187, 51.51932957 ], [ -0.02769562, 51.51935891 ], [ -0.02723591, 51.51906871 ], [ -0.02780636, 51.51869344 ], [ -0.02800419, 51.518748 ], [ -0.02830566, 51.5185709 ], [ -0.02826968, 51.51840331 ], [ -0.02808515, 51.51833726 ], [ -0.0276374, 51.51769124 ], [ -0.02871762, 51.51737667 ], [ -0.02960398, 51.51721171 ], [ -0.02986092, 51.51726998 ], [ -0.0302877, 51.51806852 ], [ -0.03022679, 51.51818796 ], [ -0.03051712, 51.5185979 ], [ -0.03097559, 51.51932383 ], [ -0.03057211, 51.51942471 ], [ -0.03061823, 51.52000148 ], [ -0.03048717, 51.51997056 ], [ -0.03051237, 51.52038801 ], [ -0.03061481, 51.5205127 ], [ -0.03056604, 51.52083849 ], [ -0.0307461, 51.52108131 ], [ -0.03047862, 51.52132713 ], [ -0.02926548, 51.52104595 ], [ -0.02840107, 51.52078224 ], [ -0.02842359, 51.52055098 ], [ -0.02891777, 51.52041953 ], [ -0.02848118, 51.52000495 ], [ -0.02747734, 51.52072812 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 70, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02830566, 51.51617612, -0.02198512, 51.51971634 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0231217, 51.51846628 ], [ -0.0229023, 51.51806816 ], [ -0.02232217, 51.51717316 ], [ -0.02198512, 51.5168149 ], [ -0.02230034, 51.51711574 ], [ -0.02430675, 51.5163039 ], [ -0.02497342, 51.51655928 ], [ -0.02507253, 51.51631742 ], [ -0.02531798, 51.51617612 ], [ -0.02608086, 51.51623929 ], [ -0.0259373, 51.51634069 ], [ -0.02529775, 51.51646481 ], [ -0.02560413, 51.51704551 ], [ -0.0267633, 51.5168009 ], [ -0.02691647, 51.51726642 ], [ -0.02739715, 51.51775983 ], [ -0.0276374, 51.51769124 ], [ -0.02808515, 51.51833726 ], [ -0.02826968, 51.51840331 ], [ -0.02830566, 51.5185709 ], [ -0.02800419, 51.518748 ], [ -0.02780636, 51.51869344 ], [ -0.02723591, 51.51906871 ], [ -0.02769562, 51.51935891 ], [ -0.02709187, 51.51932957 ], [ -0.02697506, 51.51937693 ], [ -0.02620965, 51.5193158 ], [ -0.02587359, 51.51916317 ], [ -0.02526668, 51.51899897 ], [ -0.02500321, 51.51945347 ], [ -0.02474955, 51.51971634 ], [ -0.02411616, 51.51945399 ], [ -0.0234534, 51.51898911 ], [ -0.0231217, 51.51846628 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 71, "LSOA11CD": "E01004242", "LSOA11NM": "Tower Hamlets 012C", "MSOA11CD": "E02000875", "MSOA11NM": "Tower Hamlets 012", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2453, "HHOLDRES": 2433, "COMESTRES": 20, "POPDEN": 121.600000, "HHOLDS": 898, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.03565041, 51.51391946, -0.02162257, 51.5185979 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0276374, 51.51769124 ], [ -0.02739715, 51.51775983 ], [ -0.02691647, 51.51726642 ], [ -0.0267633, 51.5168009 ], [ -0.02560413, 51.51704551 ], [ -0.02529775, 51.51646481 ], [ -0.0259373, 51.51634069 ], [ -0.02608086, 51.51623929 ], [ -0.02531798, 51.51617612 ], [ -0.02507253, 51.51631742 ], [ -0.02497342, 51.51655928 ], [ -0.02430675, 51.5163039 ], [ -0.02230034, 51.51711574 ], [ -0.02198512, 51.5168149 ], [ -0.02162257, 51.51654128 ], [ -0.02287686, 51.51601428 ], [ -0.02439177, 51.51541735 ], [ -0.02573055, 51.51485142 ], [ -0.02803005, 51.51391946 ], [ -0.0282341, 51.51428336 ], [ -0.02928086, 51.51626611 ], [ -0.03071767, 51.51603718 ], [ -0.03308705, 51.51597015 ], [ -0.03334034, 51.51655219 ], [ -0.03384028, 51.51621815 ], [ -0.03380498, 51.51641967 ], [ -0.03386494, 51.5168801 ], [ -0.03416051, 51.5172331 ], [ -0.03565041, 51.51839714 ], [ -0.03539955, 51.51852297 ], [ -0.0348728, 51.51837026 ], [ -0.03392981, 51.51784187 ], [ -0.03341902, 51.51765345 ], [ -0.03257967, 51.51739656 ], [ -0.03231701, 51.51738421 ], [ -0.03070924, 51.51848843 ], [ -0.03051712, 51.5185979 ], [ -0.03022679, 51.51818796 ], [ -0.0302877, 51.51806852 ], [ -0.02986092, 51.51726998 ], [ -0.02960398, 51.51721171 ], [ -0.02871762, 51.51737667 ], [ -0.0276374, 51.51769124 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 72, "LSOA11CD": "E01004274", "LSOA11NM": "Tower Hamlets 031A", "MSOA11CD": "E02000894", "MSOA11NM": "Tower Hamlets 031", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1973, "HHOLDRES": 1973, "COMESTRES": 0, "POPDEN": 232.400000, "HHOLDS": 654, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.0239105, 51.48761793, -0.01938156, 51.49250979 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01954267, 51.49038368 ], [ -0.01938156, 51.49016006 ], [ -0.01993907, 51.4898271 ], [ -0.0200294, 51.48965601 ], [ -0.02077415, 51.48916757 ], [ -0.02003996, 51.48880408 ], [ -0.02025833, 51.48835324 ], [ -0.02046095, 51.4884452 ], [ -0.02157809, 51.48761793 ], [ -0.02295383, 51.48837663 ], [ -0.02272834, 51.48855677 ], [ -0.02289386, 51.48881496 ], [ -0.02284847, 51.48903892 ], [ -0.02352735, 51.48917859 ], [ -0.02361931, 51.48943608 ], [ -0.0239105, 51.48968471 ], [ -0.02362992, 51.49001269 ], [ -0.02313611, 51.48954524 ], [ -0.02228254, 51.48997862 ], [ -0.02331104, 51.49077476 ], [ -0.02374515, 51.49113945 ], [ -0.02291346, 51.49150175 ], [ -0.02334638, 51.49167677 ], [ -0.02309121, 51.49179 ], [ -0.02285657, 51.49176938 ], [ -0.02282707, 51.49197164 ], [ -0.02244137, 51.49194564 ], [ -0.0215685, 51.49189828 ], [ -0.02159249, 51.49210401 ], [ -0.02122521, 51.4921953 ], [ -0.02100399, 51.49236089 ], [ -0.02098397, 51.49250979 ], [ -0.02076804, 51.4925025 ], [ -0.02069914, 51.49216653 ], [ -0.02046274, 51.4922311 ], [ -0.020222, 51.49213956 ], [ -0.02035684, 51.49197499 ], [ -0.0202708, 51.49185318 ], [ -0.02040509, 51.49166008 ], [ -0.02019277, 51.49146785 ], [ -0.02063467, 51.49119795 ], [ -0.02064953, 51.49102662 ], [ -0.02108992, 51.49083621 ], [ -0.02138306, 51.49059252 ], [ -0.02106692, 51.49041487 ], [ -0.0212931, 51.4901812 ], [ -0.02077827, 51.49012794 ], [ -0.02045262, 51.49017908 ], [ -0.02016187, 51.49050358 ], [ -0.01990975, 51.49061323 ], [ -0.01954267, 51.49038368 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 73, "LSOA11CD": "E01004274", "LSOA11NM": "Tower Hamlets 031A", "MSOA11CD": "E02000894", "MSOA11NM": "Tower Hamlets 031", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1973, "HHOLDRES": 1973, "COMESTRES": 0, "POPDEN": 232.400000, "HHOLDS": 654, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.02077415, 51.48714178, -0.01331335, 51.49084227 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01561307, 51.49068106 ], [ -0.0156736, 51.49062593 ], [ -0.01520091, 51.49027396 ], [ -0.01426382, 51.489338 ], [ -0.01417132, 51.48937395 ], [ -0.0136128, 51.48878108 ], [ -0.01342279, 51.4881811 ], [ -0.01331335, 51.48714178 ], [ -0.0133399, 51.48718894 ], [ -0.01397209, 51.48724728 ], [ -0.01438175, 51.48740721 ], [ -0.01453524, 51.4873931 ], [ -0.01452771, 51.4871551 ], [ -0.01578684, 51.48723038 ], [ -0.01622993, 51.48730981 ], [ -0.01735216, 51.48768806 ], [ -0.01749789, 51.48749647 ], [ -0.01833915, 51.48772454 ], [ -0.01833751, 51.4878205 ], [ -0.01897626, 51.48809248 ], [ -0.01920357, 51.48799269 ], [ -0.01940901, 51.48834486 ], [ -0.0192928, 51.48846931 ], [ -0.02003996, 51.48880408 ], [ -0.02077415, 51.48916757 ], [ -0.0200294, 51.48965601 ], [ -0.01993907, 51.4898271 ], [ -0.01938156, 51.49016006 ], [ -0.01954267, 51.49038368 ], [ -0.01939426, 51.49047192 ], [ -0.01927281, 51.49084227 ], [ -0.01897042, 51.49071175 ], [ -0.01860369, 51.4904381 ], [ -0.01838021, 51.49058314 ], [ -0.0182109, 51.49046091 ], [ -0.018345, 51.49030654 ], [ -0.01823512, 51.49023043 ], [ -0.01789356, 51.49040583 ], [ -0.01784948, 51.49054894 ], [ -0.01762751, 51.49058784 ], [ -0.01752491, 51.49083886 ], [ -0.01586419, 51.49075688 ], [ -0.01561307, 51.49068106 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 74, "LSOA11CD": "E01004274", "LSOA11NM": "Tower Hamlets 031A", "MSOA11CD": "E02000894", "MSOA11NM": "Tower Hamlets 031", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1973, "HHOLDRES": 1973, "COMESTRES": 0, "POPDEN": 232.400000, "HHOLDS": 654, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.02303404, 51.48451552, -0.01277645, 51.48880408 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02003996, 51.48880408 ], [ -0.0192928, 51.48846931 ], [ -0.01940901, 51.48834486 ], [ -0.01920357, 51.48799269 ], [ -0.01897626, 51.48809248 ], [ -0.01833751, 51.4878205 ], [ -0.01833915, 51.48772454 ], [ -0.01749789, 51.48749647 ], [ -0.01735216, 51.48768806 ], [ -0.01622993, 51.48730981 ], [ -0.01578684, 51.48723038 ], [ -0.01452771, 51.4871551 ], [ -0.01453524, 51.4873931 ], [ -0.01438175, 51.48740721 ], [ -0.01397209, 51.48724728 ], [ -0.0133399, 51.48718894 ], [ -0.01331335, 51.48714178 ], [ -0.01314189, 51.48629725 ], [ -0.0132691, 51.48629125 ], [ -0.01277645, 51.48451552 ], [ -0.01463691, 51.48452245 ], [ -0.01669956, 51.48462032 ], [ -0.01754154, 51.4847384 ], [ -0.0183963, 51.48489435 ], [ -0.01999953, 51.4853323 ], [ -0.02105946, 51.48571918 ], [ -0.02280426, 51.48643784 ], [ -0.02303404, 51.4865397 ], [ -0.02157809, 51.48761793 ], [ -0.02046095, 51.4884452 ], [ -0.02025833, 51.48835324 ], [ -0.02003996, 51.48880408 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 75, "LSOA11CD": "E01004256", "LSOA11NM": "Tower Hamlets 024C", "MSOA11CD": "E02000887", "MSOA11NM": "Tower Hamlets 024", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1729, "HHOLDRES": 1729, "COMESTRES": 0, "POPDEN": 120.700000, "HHOLDS": 611, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.03163278, 51.50152085, -0.01205159, 51.50972385 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01336775, 51.50735215 ], [ -0.01246922, 51.50741135 ], [ -0.01205159, 51.50752934 ], [ -0.01212675, 51.50725435 ], [ -0.01231941, 51.50654944 ], [ -0.01265269, 51.50659036 ], [ -0.01278933, 51.50609932 ], [ -0.01324025, 51.50614743 ], [ -0.01330349, 51.50591539 ], [ -0.01289656, 51.50587042 ], [ -0.01313979, 51.50499957 ], [ -0.01309848, 51.50491442 ], [ -0.01239564, 51.50463244 ], [ -0.01258175, 51.5045156 ], [ -0.01319756, 51.50474819 ], [ -0.01330024, 51.50466562 ], [ -0.01488528, 51.50483199 ], [ -0.01506307, 51.50439463 ], [ -0.01677609, 51.50459434 ], [ -0.01842616, 51.50475713 ], [ -0.01835687, 51.50502574 ], [ -0.01846777, 51.50512654 ], [ -0.02020348, 51.50530874 ], [ -0.02320054, 51.50564707 ], [ -0.02338968, 51.5056053 ], [ -0.02354225, 51.50541003 ], [ -0.02389111, 51.50543944 ], [ -0.02401626, 51.50503076 ], [ -0.0242641, 51.50506583 ], [ -0.02585154, 51.50476048 ], [ -0.02570989, 51.50460122 ], [ -0.02563981, 51.50422234 ], [ -0.0257974, 51.50391024 ], [ -0.02556116, 51.50370842 ], [ -0.02570046, 51.50348594 ], [ -0.02568449, 51.50318891 ], [ -0.02589417, 51.50233812 ], [ -0.02595832, 51.50152085 ], [ -0.02682532, 51.50156866 ], [ -0.02715062, 51.50164948 ], [ -0.0294715, 51.50160047 ], [ -0.02937584, 51.50231547 ], [ -0.02936024, 51.50276049 ], [ -0.02948824, 51.50346746 ], [ -0.02950899, 51.50392644 ], [ -0.029609, 51.50450928 ], [ -0.02991192, 51.50519122 ], [ -0.03031224, 51.50568216 ], [ -0.0308463, 51.50605815 ], [ -0.03132863, 51.50625608 ], [ -0.03163278, 51.50649205 ], [ -0.03039267, 51.50717913 ], [ -0.02953343, 51.50784702 ], [ -0.02923373, 51.50781565 ], [ -0.02909303, 51.50776305 ], [ -0.02761165, 51.50786193 ], [ -0.02727255, 51.50785102 ], [ -0.02717231, 51.50816999 ], [ -0.02689131, 51.50866998 ], [ -0.02665769, 51.5089489 ], [ -0.02617673, 51.5094069 ], [ -0.02551541, 51.50972385 ], [ -0.02515698, 51.50945876 ], [ -0.02473441, 51.50914289 ], [ -0.02416847, 51.5089209 ], [ -0.02293536, 51.50871394 ], [ -0.0217621, 51.50845711 ], [ -0.0205398, 51.50827108 ], [ -0.01924691, 51.50784416 ], [ -0.01850496, 51.5076942 ], [ -0.01605046, 51.5074283 ], [ -0.01424917, 51.50734428 ], [ -0.01336775, 51.50735215 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 76, "LSOA11CD": "E01004280", "LSOA11NM": "Tower Hamlets 032A", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 137.900000, "HHOLDS": 769, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.03017949, 51.49248858, -0.0214104, 51.4985776 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02448757, 51.49802843 ], [ -0.02473594, 51.49772556 ], [ -0.02463539, 51.49746078 ], [ -0.02286105, 51.49751181 ], [ -0.02309265, 51.49731425 ], [ -0.02325297, 51.49732173 ], [ -0.02359434, 51.49714944 ], [ -0.02426136, 51.49716502 ], [ -0.02434259, 51.49683463 ], [ -0.02303093, 51.49685819 ], [ -0.02306327, 51.49660074 ], [ -0.022786, 51.49658271 ], [ -0.02278242, 51.49633242 ], [ -0.02144871, 51.49636586 ], [ -0.0214104, 51.4963287 ], [ -0.02142523, 51.49554985 ], [ -0.0239851, 51.49550737 ], [ -0.02391231, 51.49485866 ], [ -0.02470545, 51.49448168 ], [ -0.02413885, 51.49439219 ], [ -0.02415705, 51.49370209 ], [ -0.02436834, 51.49366205 ], [ -0.0243828, 51.49350995 ], [ -0.02458924, 51.49353013 ], [ -0.02462808, 51.49394042 ], [ -0.02489571, 51.49386078 ], [ -0.02488032, 51.49318266 ], [ -0.02503682, 51.4932091 ], [ -0.02547928, 51.49297842 ], [ -0.02580183, 51.49267116 ], [ -0.02630787, 51.49248858 ], [ -0.02630715, 51.49381581 ], [ -0.02715134, 51.49380126 ], [ -0.02689846, 51.49437822 ], [ -0.02684502, 51.49478186 ], [ -0.02659407, 51.49485592 ], [ -0.02654859, 51.49505756 ], [ -0.03017949, 51.49606847 ], [ -0.03002754, 51.4977866 ], [ -0.02664477, 51.49780627 ], [ -0.02667716, 51.4980887 ], [ -0.02682548, 51.49817394 ], [ -0.02723932, 51.49820783 ], [ -0.02694192, 51.49841986 ], [ -0.02691718, 51.4985776 ], [ -0.02647381, 51.4985278 ], [ -0.02617807, 51.49834179 ], [ -0.02632809, 51.49815236 ], [ -0.02588954, 51.49811141 ], [ -0.0258689, 51.49792221 ], [ -0.02488873, 51.49793268 ], [ -0.02477637, 51.49804017 ], [ -0.02448757, 51.49802843 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 77, "LSOA11CD": "E01032774", "LSOA11NM": "Tower Hamlets 032E", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1298, "HHOLDRES": 1297, "COMESTRES": 1, "POPDEN": 63.600000, "HHOLDS": 583, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.0225226, 51.49012794, -0.01478132, 51.49384959 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01561307, 51.49068106 ], [ -0.01586419, 51.49075688 ], [ -0.01752491, 51.49083886 ], [ -0.01762751, 51.49058784 ], [ -0.01784948, 51.49054894 ], [ -0.01789356, 51.49040583 ], [ -0.01823512, 51.49023043 ], [ -0.018345, 51.49030654 ], [ -0.0182109, 51.49046091 ], [ -0.01838021, 51.49058314 ], [ -0.01860369, 51.4904381 ], [ -0.01897042, 51.49071175 ], [ -0.01927281, 51.49084227 ], [ -0.01939426, 51.49047192 ], [ -0.01954267, 51.49038368 ], [ -0.01990975, 51.49061323 ], [ -0.02016187, 51.49050358 ], [ -0.02045262, 51.49017908 ], [ -0.02077827, 51.49012794 ], [ -0.0212931, 51.4901812 ], [ -0.02106692, 51.49041487 ], [ -0.02138306, 51.49059252 ], [ -0.02108992, 51.49083621 ], [ -0.02064953, 51.49102662 ], [ -0.02063467, 51.49119795 ], [ -0.02019277, 51.49146785 ], [ -0.02040509, 51.49166008 ], [ -0.0202708, 51.49185318 ], [ -0.02035684, 51.49197499 ], [ -0.020222, 51.49213956 ], [ -0.02046274, 51.4922311 ], [ -0.02069914, 51.49216653 ], [ -0.02076804, 51.4925025 ], [ -0.02098397, 51.49250979 ], [ -0.02100399, 51.49236089 ], [ -0.02122521, 51.4921953 ], [ -0.02159249, 51.49210401 ], [ -0.0215685, 51.49189828 ], [ -0.02244137, 51.49194564 ], [ -0.0224032, 51.4921495 ], [ -0.0225226, 51.49224475 ], [ -0.02232349, 51.4924457 ], [ -0.02234771, 51.4925705 ], [ -0.02192921, 51.4925498 ], [ -0.02190032, 51.49280412 ], [ -0.02216597, 51.49292778 ], [ -0.02251205, 51.49328146 ], [ -0.02249025, 51.49335646 ], [ -0.02173226, 51.4933021 ], [ -0.01927448, 51.49317067 ], [ -0.01899203, 51.49304001 ], [ -0.01894068, 51.49289525 ], [ -0.01767621, 51.49281992 ], [ -0.01748, 51.49377714 ], [ -0.01728093, 51.49384959 ], [ -0.01733417, 51.4934605 ], [ -0.01519825, 51.49336848 ], [ -0.01478132, 51.49334157 ], [ -0.0149528, 51.49254467 ], [ -0.01534112, 51.49173078 ], [ -0.01554189, 51.49141971 ], [ -0.01543877, 51.49080884 ], [ -0.01561307, 51.49068106 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 78, "LSOA11CD": "E01004324", "LSOA11NM": "Tower Hamlets 017C", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1574, "HHOLDRES": 1570, "COMESTRES": 4, "POPDEN": 206.800000, "HHOLDS": 485, "AVHHOLDSZ": 3.200000 }, "bbox": [ -0.05127757, 51.51538907, -0.04438378, 51.52051203 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04549934, 51.51915391 ], [ -0.04531869, 51.51891363 ], [ -0.04499426, 51.51868796 ], [ -0.0452968, 51.51828002 ], [ -0.04496818, 51.51824223 ], [ -0.04438378, 51.51808861 ], [ -0.04457302, 51.51737234 ], [ -0.04451971, 51.51659807 ], [ -0.04558247, 51.51668773 ], [ -0.04553764, 51.51623199 ], [ -0.04604202, 51.51597699 ], [ -0.04640242, 51.51595849 ], [ -0.04664889, 51.51611344 ], [ -0.0468624, 51.5160909 ], [ -0.04674357, 51.51557617 ], [ -0.04709522, 51.51538907 ], [ -0.0475669, 51.51578553 ], [ -0.04792389, 51.51574228 ], [ -0.04823606, 51.51600025 ], [ -0.04830849, 51.51622287 ], [ -0.04851049, 51.5162182 ], [ -0.04876987, 51.51681275 ], [ -0.04981475, 51.51681214 ], [ -0.04987515, 51.51681812 ], [ -0.04981922, 51.51681292 ], [ -0.04963771, 51.51838364 ], [ -0.0501833, 51.51841267 ], [ -0.05013369, 51.51868861 ], [ -0.05062064, 51.51876166 ], [ -0.05048272, 51.51924863 ], [ -0.05127757, 51.51929377 ], [ -0.05117917, 51.51928986 ], [ -0.05125711, 51.51969386 ], [ -0.05103664, 51.51977487 ], [ -0.05071904, 51.52009428 ], [ -0.04996863, 51.52028247 ], [ -0.04955134, 51.52025747 ], [ -0.04941858, 51.52004062 ], [ -0.04906724, 51.52022426 ], [ -0.04923173, 51.52033661 ], [ -0.04896476, 51.52051203 ], [ -0.04799161, 51.51994153 ], [ -0.04733212, 51.52007123 ], [ -0.04720517, 51.51979968 ], [ -0.04672458, 51.5195986 ], [ -0.0463818, 51.51958421 ], [ -0.04635455, 51.51945715 ], [ -0.04605595, 51.51944717 ], [ -0.04576896, 51.51953726 ], [ -0.04549934, 51.51915391 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 79, "LSOA11CD": "E01004288", "LSOA11NM": "Tower Hamlets 019D", "MSOA11CD": "E02000882", "MSOA11NM": "Tower Hamlets 019", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1620, "HHOLDRES": 1590, "COMESTRES": 30, "POPDEN": 157.600000, "HHOLDS": 525, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.04549934, 51.5165911, -0.03565041, 51.52141362 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03644733, 51.52141162 ], [ -0.03635615, 51.52011766 ], [ -0.03624726, 51.51913084 ], [ -0.03612635, 51.51882081 ], [ -0.03565041, 51.51839714 ], [ -0.0360597, 51.51825525 ], [ -0.03806916, 51.51811803 ], [ -0.03856159, 51.51806331 ], [ -0.03864401, 51.51843717 ], [ -0.03948554, 51.51837661 ], [ -0.03945898, 51.51818661 ], [ -0.03894588, 51.51801791 ], [ -0.04060216, 51.51787261 ], [ -0.04216546, 51.51771886 ], [ -0.04269917, 51.51770978 ], [ -0.04261231, 51.51671013 ], [ -0.044102, 51.5165911 ], [ -0.04451971, 51.51659807 ], [ -0.04457302, 51.51737234 ], [ -0.04438378, 51.51808861 ], [ -0.04496818, 51.51824223 ], [ -0.0452968, 51.51828002 ], [ -0.04499426, 51.51868796 ], [ -0.04531869, 51.51891363 ], [ -0.04549934, 51.51915391 ], [ -0.04464485, 51.51939692 ], [ -0.04419531, 51.5187869 ], [ -0.0440327, 51.5186614 ], [ -0.04378715, 51.5186824 ], [ -0.04365336, 51.51885343 ], [ -0.04376166, 51.51903808 ], [ -0.04400247, 51.51920007 ], [ -0.04400267, 51.51940802 ], [ -0.04413447, 51.51963927 ], [ -0.04374369, 51.519803 ], [ -0.04352994, 51.51951321 ], [ -0.0425577, 51.51964087 ], [ -0.04263897, 51.51975131 ], [ -0.04226839, 51.51978776 ], [ -0.04239373, 51.52042722 ], [ -0.03907459, 51.52111568 ], [ -0.0379267, 51.52130654 ], [ -0.03696169, 51.52141362 ], [ -0.03644733, 51.52141162 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 80, "LSOA11CD": "E01004288", "LSOA11NM": "Tower Hamlets 019D", "MSOA11CD": "E02000882", "MSOA11NM": "Tower Hamlets 019", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1620, "HHOLDRES": 1590, "COMESTRES": 30, "POPDEN": 157.600000, "HHOLDS": 525, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.04269917, 51.51527794, -0.03380498, 51.51843717 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03380498, 51.51641967 ], [ -0.03495876, 51.51567329 ], [ -0.03491779, 51.51632066 ], [ -0.03556632, 51.51632253 ], [ -0.03564262, 51.51668423 ], [ -0.035821, 51.51667638 ], [ -0.03587348, 51.51682874 ], [ -0.0363825, 51.51676875 ], [ -0.03642973, 51.51635497 ], [ -0.03678942, 51.51636999 ], [ -0.03685554, 51.51617208 ], [ -0.03742189, 51.51619551 ], [ -0.03746788, 51.51587923 ], [ -0.03791427, 51.51570263 ], [ -0.03810878, 51.51545331 ], [ -0.03796584, 51.51528035 ], [ -0.03867493, 51.51527794 ], [ -0.03871288, 51.51566576 ], [ -0.03912231, 51.51557902 ], [ -0.03940742, 51.51563267 ], [ -0.0398313, 51.51588471 ], [ -0.03997712, 51.51620946 ], [ -0.04024984, 51.51633519 ], [ -0.04060337, 51.51632019 ], [ -0.04161179, 51.51641984 ], [ -0.04214365, 51.51654508 ], [ -0.04219937, 51.51642255 ], [ -0.04261231, 51.51671013 ], [ -0.04269917, 51.51770978 ], [ -0.04216546, 51.51771886 ], [ -0.04060216, 51.51787261 ], [ -0.03894588, 51.51801791 ], [ -0.03945898, 51.51818661 ], [ -0.03948554, 51.51837661 ], [ -0.03864401, 51.51843717 ], [ -0.03856159, 51.51806331 ], [ -0.03806916, 51.51811803 ], [ -0.0360597, 51.51825525 ], [ -0.03565041, 51.51839714 ], [ -0.03416051, 51.5172331 ], [ -0.03386494, 51.5168801 ], [ -0.03380498, 51.51641967 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 81, "LSOA11CD": "E01004288", "LSOA11NM": "Tower Hamlets 019D", "MSOA11CD": "E02000882", "MSOA11NM": "Tower Hamlets 019", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1620, "HHOLDRES": 1590, "COMESTRES": 30, "POPDEN": 157.600000, "HHOLDS": 525, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.04219937, 51.51251439, -0.03380498, 51.51682874 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03380498, 51.51641967 ], [ -0.03384028, 51.51621815 ], [ -0.03408556, 51.51571023 ], [ -0.03430697, 51.51538022 ], [ -0.03552861, 51.51403992 ], [ -0.03603881, 51.51342239 ], [ -0.03625405, 51.51308834 ], [ -0.0364436, 51.51251439 ], [ -0.03875363, 51.51263636 ], [ -0.04016765, 51.51269631 ], [ -0.04121514, 51.51279028 ], [ -0.04102237, 51.51310408 ], [ -0.04116553, 51.51327403 ], [ -0.04164884, 51.51324343 ], [ -0.04157839, 51.51354353 ], [ -0.04144704, 51.51356728 ], [ -0.0413216, 51.51394112 ], [ -0.04092216, 51.51391763 ], [ -0.04069871, 51.51413043 ], [ -0.04086109, 51.51434788 ], [ -0.04113046, 51.51441035 ], [ -0.04117821, 51.51452621 ], [ -0.04047581, 51.51453524 ], [ -0.04008939, 51.51425104 ], [ -0.03969536, 51.51424019 ], [ -0.0396483, 51.51457533 ], [ -0.04016258, 51.51468182 ], [ -0.04093813, 51.51477973 ], [ -0.0409768, 51.51529702 ], [ -0.040701, 51.51544815 ], [ -0.04069705, 51.51566196 ], [ -0.04147403, 51.51569293 ], [ -0.04159518, 51.51589279 ], [ -0.04219937, 51.51642255 ], [ -0.04214365, 51.51654508 ], [ -0.04161179, 51.51641984 ], [ -0.04060337, 51.51632019 ], [ -0.04024984, 51.51633519 ], [ -0.03997712, 51.51620946 ], [ -0.0398313, 51.51588471 ], [ -0.03940742, 51.51563267 ], [ -0.03912231, 51.51557902 ], [ -0.03871288, 51.51566576 ], [ -0.03867493, 51.51527794 ], [ -0.03796584, 51.51528035 ], [ -0.03810878, 51.51545331 ], [ -0.03791427, 51.51570263 ], [ -0.03746788, 51.51587923 ], [ -0.03742189, 51.51619551 ], [ -0.03685554, 51.51617208 ], [ -0.03678942, 51.51636999 ], [ -0.03642973, 51.51635497 ], [ -0.0363825, 51.51676875 ], [ -0.03587348, 51.51682874 ], [ -0.035821, 51.51667638 ], [ -0.03564262, 51.51668423 ], [ -0.03556632, 51.51632253 ], [ -0.03491779, 51.51632066 ], [ -0.03495876, 51.51567329 ], [ -0.03380498, 51.51641967 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 82, "LSOA11CD": "E01004323", "LSOA11NM": "Tower Hamlets 017B", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1466, "HHOLDRES": 1466, "COMESTRES": 0, "POPDEN": 207.400000, "HHOLDS": 480, "AVHHOLDSZ": 3.100000 }, "bbox": [ -0.05322315, 51.51356752, -0.04915613, 51.5170947 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04981475, 51.51681214 ], [ -0.04983921, 51.51652821 ], [ -0.04935905, 51.51650565 ], [ -0.04936955, 51.51584982 ], [ -0.04919428, 51.51585055 ], [ -0.04915613, 51.51563768 ], [ -0.04951068, 51.51553409 ], [ -0.04944181, 51.51477779 ], [ -0.04958625, 51.5148046 ], [ -0.05004888, 51.51450163 ], [ -0.04956076, 51.51431154 ], [ -0.04963561, 51.5140295 ], [ -0.0493747, 51.51374674 ], [ -0.0494567, 51.51356752 ], [ -0.0515536, 51.51391936 ], [ -0.05263037, 51.51405613 ], [ -0.05322315, 51.51407609 ], [ -0.05311263, 51.51536979 ], [ -0.05296102, 51.51708271 ], [ -0.05296018, 51.5170947 ], [ -0.04987515, 51.51681812 ], [ -0.04981475, 51.51681214 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 83, "LSOA11CD": "E01004289", "LSOA11NM": "Tower Hamlets 016C", "MSOA11CD": "E02000879", "MSOA11NM": "Tower Hamlets 016", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1844, "HHOLDRES": 1844, "COMESTRES": 0, "POPDEN": 175.800000, "HHOLDS": 670, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.04559006, 51.51279028, -0.0396483, 51.51671013 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04219937, 51.51642255 ], [ -0.04159518, 51.51589279 ], [ -0.04147403, 51.51569293 ], [ -0.04069705, 51.51566196 ], [ -0.040701, 51.51544815 ], [ -0.0409768, 51.51529702 ], [ -0.04093813, 51.51477973 ], [ -0.04016258, 51.51468182 ], [ -0.0396483, 51.51457533 ], [ -0.03969536, 51.51424019 ], [ -0.04008939, 51.51425104 ], [ -0.04047581, 51.51453524 ], [ -0.04117821, 51.51452621 ], [ -0.04113046, 51.51441035 ], [ -0.04086109, 51.51434788 ], [ -0.04069871, 51.51413043 ], [ -0.04092216, 51.51391763 ], [ -0.0413216, 51.51394112 ], [ -0.04144704, 51.51356728 ], [ -0.04157839, 51.51354353 ], [ -0.04164884, 51.51324343 ], [ -0.04116553, 51.51327403 ], [ -0.04102237, 51.51310408 ], [ -0.04121514, 51.51279028 ], [ -0.04187941, 51.51289942 ], [ -0.0433796, 51.51310024 ], [ -0.04368871, 51.51311823 ], [ -0.04355777, 51.51314677 ], [ -0.04358134, 51.5136058 ], [ -0.04411198, 51.51359978 ], [ -0.04407396, 51.51390755 ], [ -0.04466282, 51.51392959 ], [ -0.04463611, 51.51421692 ], [ -0.04359721, 51.51424455 ], [ -0.04360832, 51.51448557 ], [ -0.04460031, 51.5144743 ], [ -0.04464342, 51.51454714 ], [ -0.04513506, 51.5145373 ], [ -0.04512137, 51.51485699 ], [ -0.04544852, 51.51487485 ], [ -0.04559006, 51.51508201 ], [ -0.04503516, 51.51544383 ], [ -0.04550869, 51.51546074 ], [ -0.04553764, 51.51623199 ], [ -0.04558247, 51.51668773 ], [ -0.04451971, 51.51659807 ], [ -0.044102, 51.5165911 ], [ -0.04261231, 51.51671013 ], [ -0.04219937, 51.51642255 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 84, "LSOA11CD": "E01004289", "LSOA11NM": "Tower Hamlets 016C", "MSOA11CD": "E02000879", "MSOA11NM": "Tower Hamlets 016", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1844, "HHOLDRES": 1844, "COMESTRES": 0, "POPDEN": 175.800000, "HHOLDS": 670, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.05004888, 51.51310632, -0.04355777, 51.51681275 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04553764, 51.51623199 ], [ -0.04550869, 51.51546074 ], [ -0.04503516, 51.51544383 ], [ -0.04559006, 51.51508201 ], [ -0.04544852, 51.51487485 ], [ -0.04512137, 51.51485699 ], [ -0.04513506, 51.5145373 ], [ -0.04464342, 51.51454714 ], [ -0.04460031, 51.5144743 ], [ -0.04360832, 51.51448557 ], [ -0.04359721, 51.51424455 ], [ -0.04463611, 51.51421692 ], [ -0.04466282, 51.51392959 ], [ -0.04407396, 51.51390755 ], [ -0.04411198, 51.51359978 ], [ -0.04358134, 51.5136058 ], [ -0.04355777, 51.51314677 ], [ -0.04368871, 51.51311823 ], [ -0.04432159, 51.51311749 ], [ -0.04561509, 51.51310632 ], [ -0.04679263, 51.5131643 ], [ -0.04777136, 51.51330018 ], [ -0.0494567, 51.51356752 ], [ -0.0493747, 51.51374674 ], [ -0.04963561, 51.5140295 ], [ -0.04956076, 51.51431154 ], [ -0.05004888, 51.51450163 ], [ -0.04958625, 51.5148046 ], [ -0.04944181, 51.51477779 ], [ -0.04951068, 51.51553409 ], [ -0.04915613, 51.51563768 ], [ -0.04919428, 51.51585055 ], [ -0.04936955, 51.51584982 ], [ -0.04935905, 51.51650565 ], [ -0.04983921, 51.51652821 ], [ -0.04981475, 51.51681214 ], [ -0.04876987, 51.51681275 ], [ -0.04851049, 51.5162182 ], [ -0.04830849, 51.51622287 ], [ -0.04823606, 51.51600025 ], [ -0.04792389, 51.51574228 ], [ -0.0475669, 51.51578553 ], [ -0.04709522, 51.51538907 ], [ -0.04674357, 51.51557617 ], [ -0.0468624, 51.5160909 ], [ -0.04664889, 51.51611344 ], [ -0.04640242, 51.51595849 ], [ -0.04604202, 51.51597699 ], [ -0.04553764, 51.51623199 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 85, "LSOA11CD": "E01004208", "LSOA11NM": "Tower Hamlets 013C", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1976, "HHOLDRES": 1842, "COMESTRES": 134, "POPDEN": 122.100000, "HHOLDS": 788, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05296427, 51.5186614, -0.04226839, 51.52193938 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04239373, 51.52042722 ], [ -0.04226839, 51.51978776 ], [ -0.04263897, 51.51975131 ], [ -0.0425577, 51.51964087 ], [ -0.04352994, 51.51951321 ], [ -0.04374369, 51.519803 ], [ -0.04413447, 51.51963927 ], [ -0.04400267, 51.51940802 ], [ -0.04400247, 51.51920007 ], [ -0.04376166, 51.51903808 ], [ -0.04365336, 51.51885343 ], [ -0.04378715, 51.5186824 ], [ -0.0440327, 51.5186614 ], [ -0.04419531, 51.5187869 ], [ -0.04464485, 51.51939692 ], [ -0.04549934, 51.51915391 ], [ -0.04576896, 51.51953726 ], [ -0.04605595, 51.51944717 ], [ -0.04635455, 51.51945715 ], [ -0.0463818, 51.51958421 ], [ -0.04672458, 51.5195986 ], [ -0.04720517, 51.51979968 ], [ -0.04733212, 51.52007123 ], [ -0.04799161, 51.51994153 ], [ -0.04896476, 51.52051203 ], [ -0.04923173, 51.52033661 ], [ -0.04906724, 51.52022426 ], [ -0.04941858, 51.52004062 ], [ -0.04955134, 51.52025747 ], [ -0.04996863, 51.52028247 ], [ -0.05071904, 51.52009428 ], [ -0.05103664, 51.51977487 ], [ -0.05125711, 51.51969386 ], [ -0.05117917, 51.51928986 ], [ -0.05127757, 51.51929377 ], [ -0.05169784, 51.5193166 ], [ -0.05165078, 51.5197226 ], [ -0.05272119, 51.51971958 ], [ -0.05283379, 51.52005475 ], [ -0.05296427, 51.52039948 ], [ -0.05095189, 51.52082217 ], [ -0.0490225, 51.52125149 ], [ -0.046207, 51.52181744 ], [ -0.04564139, 51.52193938 ], [ -0.0449258, 51.52092136 ], [ -0.04402305, 51.52009458 ], [ -0.04239373, 51.52042722 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 86, "LSOA11CD": "E01004293", "LSOA11NM": "Tower Hamlets 027B", "MSOA11CD": "E02000890", "MSOA11NM": "Tower Hamlets 027", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2125, "HHOLDRES": 2125, "COMESTRES": 0, "POPDEN": 65.100000, "HHOLDS": 1133, "AVHHOLDSZ": 1.900000 }, "bbox": [ -0.06499601, 51.50161026, -0.05339262, 51.50619373 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05615055, 51.50510979 ], [ -0.05564746, 51.50474174 ], [ -0.05505788, 51.5050815 ], [ -0.05339262, 51.50352759 ], [ -0.05485276, 51.50274115 ], [ -0.05595876, 51.50233711 ], [ -0.05720572, 51.50202716 ], [ -0.05880213, 51.50175824 ], [ -0.05987107, 51.50161026 ], [ -0.06088395, 51.50165821 ], [ -0.06308607, 51.50194921 ], [ -0.06421275, 51.50211705 ], [ -0.06481161, 51.50224001 ], [ -0.06499601, 51.50227957 ], [ -0.06423385, 51.5037477 ], [ -0.06420991, 51.50383193 ], [ -0.06325875, 51.50365367 ], [ -0.06307177, 51.50432504 ], [ -0.06259019, 51.50412824 ], [ -0.06139677, 51.5041085 ], [ -0.06139284, 51.50517859 ], [ -0.05930104, 51.50523392 ], [ -0.05939131, 51.50616167 ], [ -0.05861179, 51.50619373 ], [ -0.05855889, 51.50574322 ], [ -0.05816678, 51.50547593 ], [ -0.05787156, 51.5050727 ], [ -0.05748167, 51.50476571 ], [ -0.057122, 51.50484646 ], [ -0.05691285, 51.50476621 ], [ -0.05615055, 51.50510979 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 87, "LSOA11CD": "E01004293", "LSOA11NM": "Tower Hamlets 027B", "MSOA11CD": "E02000890", "MSOA11NM": "Tower Hamlets 027", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2125, "HHOLDRES": 2125, "COMESTRES": 0, "POPDEN": 65.100000, "HHOLDS": 1133, "AVHHOLDSZ": 1.900000 }, "bbox": [ -0.06672627, 51.50365367, -0.05930104, 51.50873128 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05939131, 51.50616167 ], [ -0.05930104, 51.50523392 ], [ -0.06139284, 51.50517859 ], [ -0.06139677, 51.5041085 ], [ -0.06259019, 51.50412824 ], [ -0.06307177, 51.50432504 ], [ -0.06325875, 51.50365367 ], [ -0.06420991, 51.50383193 ], [ -0.06424507, 51.50384082 ], [ -0.06397658, 51.50473567 ], [ -0.06427849, 51.50491875 ], [ -0.06453264, 51.50474861 ], [ -0.06479575, 51.50476618 ], [ -0.06492494, 51.50489699 ], [ -0.06483688, 51.50505483 ], [ -0.0652107, 51.50519669 ], [ -0.06641865, 51.50593603 ], [ -0.0667191, 51.50632768 ], [ -0.06672627, 51.5064986 ], [ -0.06639067, 51.50659213 ], [ -0.06631834, 51.50641996 ], [ -0.06610911, 51.50630476 ], [ -0.06588832, 51.50635211 ], [ -0.06567535, 51.50656878 ], [ -0.06502942, 51.50668878 ], [ -0.06486567, 51.5070987 ], [ -0.0652325, 51.50739939 ], [ -0.06509921, 51.50748801 ], [ -0.06463763, 51.50749838 ], [ -0.06436935, 51.50736805 ], [ -0.06409003, 51.50749833 ], [ -0.06363075, 51.50752267 ], [ -0.06307272, 51.50828244 ], [ -0.06368413, 51.50848511 ], [ -0.06376019, 51.50865743 ], [ -0.06090012, 51.50872931 ], [ -0.06084042, 51.50873128 ], [ -0.06065502, 51.50757618 ], [ -0.06084671, 51.50725789 ], [ -0.0604178, 51.50720683 ], [ -0.06030914, 51.50695769 ], [ -0.06072682, 51.50689065 ], [ -0.06068427, 51.50661505 ], [ -0.06086281, 51.50609787 ], [ -0.06062896, 51.50597403 ], [ -0.0603473, 51.50608307 ], [ -0.05994064, 51.50605869 ], [ -0.05983809, 51.50616007 ], [ -0.05939131, 51.50616167 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 88, "LSOA11CD": "E01032739", "LSOA11NM": "City of London 001F", "MSOA11CD": "E02000001", "MSOA11NM": "City of London 001", "LAD11CD": "E09000001", "LAD11NM": "City of London", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1044, "HHOLDRES": 1002, "COMESTRES": 42, "POPDEN": 6.300000, "HHOLDS": 676, "AVHHOLDSZ": 1.500000 }, "bbox": [ -0.08018118, 51.50224001, -0.06397658, 51.51048076 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07321023, 51.50994863 ], [ -0.07358381, 51.50961511 ], [ -0.07376724, 51.50936632 ], [ -0.07334052, 51.50889169 ], [ -0.07167912, 51.50830683 ], [ -0.07126414, 51.50823705 ], [ -0.07050999, 51.50835054 ], [ -0.0702533, 51.50750605 ], [ -0.07005397, 51.50741085 ], [ -0.06986796, 51.50765861 ], [ -0.06944912, 51.50802287 ], [ -0.06906153, 51.50827544 ], [ -0.06893539, 51.5080998 ], [ -0.06839087, 51.50768616 ], [ -0.06824111, 51.50777993 ], [ -0.06688368, 51.50812702 ], [ -0.06667072, 51.50781069 ], [ -0.06664388, 51.50742356 ], [ -0.06573436, 51.50746252 ], [ -0.06542364, 51.50731351 ], [ -0.0652325, 51.50739939 ], [ -0.06486567, 51.5070987 ], [ -0.06502942, 51.50668878 ], [ -0.06567535, 51.50656878 ], [ -0.06588832, 51.50635211 ], [ -0.06610911, 51.50630476 ], [ -0.06631834, 51.50641996 ], [ -0.06639067, 51.50659213 ], [ -0.06672627, 51.5064986 ], [ -0.0667191, 51.50632768 ], [ -0.06641865, 51.50593603 ], [ -0.0652107, 51.50519669 ], [ -0.06483688, 51.50505483 ], [ -0.06492494, 51.50489699 ], [ -0.06479575, 51.50476618 ], [ -0.06453264, 51.50474861 ], [ -0.06427849, 51.50491875 ], [ -0.06397658, 51.50473567 ], [ -0.06424507, 51.50384082 ], [ -0.06420991, 51.50383193 ], [ -0.06423385, 51.5037477 ], [ -0.06499601, 51.50227957 ], [ -0.06481161, 51.50224001 ], [ -0.06589626, 51.50247011 ], [ -0.06769764, 51.50295395 ], [ -0.06788759, 51.50297689 ], [ -0.06911892, 51.50331192 ], [ -0.07008101, 51.50360386 ], [ -0.07089977, 51.50392084 ], [ -0.07269929, 51.50472873 ], [ -0.07318209, 51.50489769 ], [ -0.07403677, 51.50513262 ], [ -0.07521978, 51.50539865 ], [ -0.07819824, 51.50625249 ], [ -0.07881959, 51.50640445 ], [ -0.08018118, 51.50679433 ], [ -0.07965078, 51.50769222 ], [ -0.07939173, 51.50779084 ], [ -0.07918491, 51.5077616 ], [ -0.07900509, 51.50813972 ], [ -0.07908538, 51.50817926 ], [ -0.07864848, 51.50873752 ], [ -0.07865399, 51.50886351 ], [ -0.07892849, 51.50903957 ], [ -0.07882416, 51.50935738 ], [ -0.07850934, 51.50938827 ], [ -0.07788095, 51.50993924 ], [ -0.07738138, 51.51008112 ], [ -0.07683024, 51.51010005 ], [ -0.07689079, 51.51041396 ], [ -0.07627738, 51.51048076 ], [ -0.0761519, 51.51042321 ], [ -0.07609177, 51.50999056 ], [ -0.07574883, 51.51002778 ], [ -0.07567909, 51.50980182 ], [ -0.07551122, 51.50968146 ], [ -0.07476416, 51.50990427 ], [ -0.07437314, 51.50982127 ], [ -0.07361293, 51.5099923 ], [ -0.07321023, 51.50994863 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 89, "LSOA11CD": "E01032767", "LSOA11NM": "Tower Hamlets 021F", "MSOA11CD": "E02000884", "MSOA11NM": "Tower Hamlets 021", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1584, "HHOLDRES": 1584, "COMESTRES": 0, "POPDEN": 117.900000, "HHOLDS": 767, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.07376724, 51.50731351, -0.0600131, 51.51116855 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0604929, 51.50939045 ], [ -0.06023201, 51.50941427 ], [ -0.06016071, 51.5094208 ], [ -0.0600131, 51.50882484 ], [ -0.06090012, 51.50872931 ], [ -0.06376019, 51.50865743 ], [ -0.06368413, 51.50848511 ], [ -0.06307272, 51.50828244 ], [ -0.06363075, 51.50752267 ], [ -0.06409003, 51.50749833 ], [ -0.06436935, 51.50736805 ], [ -0.06463763, 51.50749838 ], [ -0.06509921, 51.50748801 ], [ -0.0652325, 51.50739939 ], [ -0.06542364, 51.50731351 ], [ -0.06573436, 51.50746252 ], [ -0.06664388, 51.50742356 ], [ -0.06667072, 51.50781069 ], [ -0.06688368, 51.50812702 ], [ -0.06824111, 51.50777993 ], [ -0.06839087, 51.50768616 ], [ -0.06893539, 51.5080998 ], [ -0.06906153, 51.50827544 ], [ -0.06944912, 51.50802287 ], [ -0.06986796, 51.50765861 ], [ -0.07005397, 51.50741085 ], [ -0.0702533, 51.50750605 ], [ -0.07050999, 51.50835054 ], [ -0.07126414, 51.50823705 ], [ -0.07167912, 51.50830683 ], [ -0.07334052, 51.50889169 ], [ -0.07376724, 51.50936632 ], [ -0.07358381, 51.50961511 ], [ -0.07321023, 51.50994863 ], [ -0.07284941, 51.51002837 ], [ -0.07270713, 51.51013409 ], [ -0.07274413, 51.51075112 ], [ -0.06977509, 51.5109271 ], [ -0.06686061, 51.5111302 ], [ -0.0663052, 51.51116855 ], [ -0.06609033, 51.51096658 ], [ -0.06599681, 51.51045245 ], [ -0.06587559, 51.51045933 ], [ -0.06573133, 51.51022429 ], [ -0.06579643, 51.50976262 ], [ -0.06586803, 51.50971587 ], [ -0.06578675, 51.5093069 ], [ -0.06463536, 51.50925193 ], [ -0.06203973, 51.50929 ], [ -0.06118815, 51.50932089 ], [ -0.0604929, 51.50939045 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 90, "LSOA11CD": "E01004304", "LSOA11NM": "Tower Hamlets 022C", "MSOA11CD": "E02000885", "MSOA11NM": "Tower Hamlets 022", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1957, "HHOLDRES": 1955, "COMESTRES": 2, "POPDEN": 190.400000, "HHOLDS": 653, "AVHHOLDSZ": 3.000000 }, "bbox": [ -0.0663052, 51.50925193, -0.0604929, 51.51149126 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06099978, 51.51105554 ], [ -0.0604929, 51.50939045 ], [ -0.06118815, 51.50932089 ], [ -0.06203973, 51.50929 ], [ -0.06463536, 51.50925193 ], [ -0.06578675, 51.5093069 ], [ -0.06586803, 51.50971587 ], [ -0.06579643, 51.50976262 ], [ -0.06573133, 51.51022429 ], [ -0.06587559, 51.51045933 ], [ -0.06599681, 51.51045245 ], [ -0.06609033, 51.51096658 ], [ -0.0663052, 51.51116855 ], [ -0.0648347, 51.51126427 ], [ -0.06380131, 51.51131227 ], [ -0.06109723, 51.51149126 ], [ -0.06099978, 51.51105554 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 91, "LSOA11CD": "E01004301", "LSOA11NM": "Tower Hamlets 025B", "MSOA11CD": "E02000888", "MSOA11NM": "Tower Hamlets 025", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1324, "HHOLDRES": 1324, "COMESTRES": 0, "POPDEN": 161.900000, "HHOLDS": 413, "AVHHOLDSZ": 3.200000 }, "bbox": [ -0.06090012, 51.50476571, -0.05514323, 51.50967535 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05615055, 51.50510979 ], [ -0.05691285, 51.50476621 ], [ -0.057122, 51.50484646 ], [ -0.05748167, 51.50476571 ], [ -0.05787156, 51.5050727 ], [ -0.05816678, 51.50547593 ], [ -0.05855889, 51.50574322 ], [ -0.05861179, 51.50619373 ], [ -0.05939131, 51.50616167 ], [ -0.05983809, 51.50616007 ], [ -0.05994064, 51.50605869 ], [ -0.0603473, 51.50608307 ], [ -0.06062896, 51.50597403 ], [ -0.06086281, 51.50609787 ], [ -0.06068427, 51.50661505 ], [ -0.06072682, 51.50689065 ], [ -0.06030914, 51.50695769 ], [ -0.0604178, 51.50720683 ], [ -0.06084671, 51.50725789 ], [ -0.06065502, 51.50757618 ], [ -0.06084042, 51.50873128 ], [ -0.06090012, 51.50872931 ], [ -0.0600131, 51.50882484 ], [ -0.06016071, 51.5094208 ], [ -0.06023201, 51.50941427 ], [ -0.05815262, 51.50962138 ], [ -0.05750386, 51.50966937 ], [ -0.05681508, 51.50967535 ], [ -0.05683482, 51.50833156 ], [ -0.05677681, 51.50771826 ], [ -0.05601268, 51.50726563 ], [ -0.05560106, 51.50680894 ], [ -0.05524439, 51.50681623 ], [ -0.05514323, 51.50663115 ], [ -0.0557153, 51.50638091 ], [ -0.05556628, 51.50633794 ], [ -0.05562484, 51.50607333 ], [ -0.05604182, 51.5059713 ], [ -0.05583983, 51.5054831 ], [ -0.05558516, 51.50549448 ], [ -0.0554108, 51.50533658 ], [ -0.05542007, 51.50516931 ], [ -0.05581506, 51.5052583 ], [ -0.05615055, 51.50510979 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 92, "LSOA11CD": "E01004303", "LSOA11NM": "Tower Hamlets 025D", "MSOA11CD": "E02000888", "MSOA11NM": "Tower Hamlets 025", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2362, "HHOLDRES": 2362, "COMESTRES": 0, "POPDEN": 106.500000, "HHOLDS": 967, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.05683482, 51.50352759, -0.04637717, 51.50967535 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05526888, 51.50954204 ], [ -0.05506901, 51.50806763 ], [ -0.05390565, 51.50812365 ], [ -0.05226485, 51.50805468 ], [ -0.05131691, 51.5080437 ], [ -0.04637717, 51.50744273 ], [ -0.04693375, 51.50716984 ], [ -0.0481275, 51.5065289 ], [ -0.04943116, 51.50578087 ], [ -0.05141265, 51.50461791 ], [ -0.05239608, 51.5041121 ], [ -0.05339262, 51.50352759 ], [ -0.05505788, 51.5050815 ], [ -0.05564746, 51.50474174 ], [ -0.05615055, 51.50510979 ], [ -0.05581506, 51.5052583 ], [ -0.05542007, 51.50516931 ], [ -0.0554108, 51.50533658 ], [ -0.05558516, 51.50549448 ], [ -0.05583983, 51.5054831 ], [ -0.05604182, 51.5059713 ], [ -0.05562484, 51.50607333 ], [ -0.05556628, 51.50633794 ], [ -0.0557153, 51.50638091 ], [ -0.05514323, 51.50663115 ], [ -0.05524439, 51.50681623 ], [ -0.05560106, 51.50680894 ], [ -0.05601268, 51.50726563 ], [ -0.05677681, 51.50771826 ], [ -0.05683482, 51.50833156 ], [ -0.05681508, 51.50967535 ], [ -0.05526888, 51.50954204 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 93, "LSOA11CD": "E01004326", "LSOA11NM": "Tower Hamlets 017D", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1444, "HHOLDRES": 1438, "COMESTRES": 6, "POPDEN": 172.500000, "HHOLDS": 623, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05689514, 51.5113739, -0.04984527, 51.51438539 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05082783, 51.5113739 ], [ -0.05101043, 51.51142572 ], [ -0.05098817, 51.51198956 ], [ -0.05190906, 51.51194956 ], [ -0.05302067, 51.51191027 ], [ -0.05303015, 51.51182829 ], [ -0.05361627, 51.51182967 ], [ -0.05362251, 51.51201929 ], [ -0.05522839, 51.5120024 ], [ -0.05543163, 51.5120296 ], [ -0.05537714, 51.5128785 ], [ -0.05623689, 51.51289899 ], [ -0.05631984, 51.5129813 ], [ -0.05685421, 51.51296241 ], [ -0.05689514, 51.51296505 ], [ -0.056718, 51.51438539 ], [ -0.05491359, 51.51419111 ], [ -0.05322315, 51.51407609 ], [ -0.05263037, 51.51405613 ], [ -0.0515536, 51.51391936 ], [ -0.05172138, 51.51295144 ], [ -0.05097564, 51.51294504 ], [ -0.05082426, 51.51309697 ], [ -0.05008837, 51.51280528 ], [ -0.04984527, 51.51257404 ], [ -0.04995706, 51.51205289 ], [ -0.05035366, 51.51201712 ], [ -0.05063923, 51.51172151 ], [ -0.05082783, 51.5113739 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 94, "LSOA11CD": "E01004300", "LSOA11NM": "Tower Hamlets 022B", "MSOA11CD": "E02000885", "MSOA11NM": "Tower Hamlets 022", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1349, "HHOLDRES": 1349, "COMESTRES": 0, "POPDEN": 258.400000, "HHOLDS": 522, "AVHHOLDSZ": 2.600000 }, "bbox": [ -0.05259676, 51.50964635, -0.04688535, 51.51198956 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05082783, 51.5113739 ], [ -0.05077129, 51.51132792 ], [ -0.05023629, 51.51137766 ], [ -0.05033862, 51.51069392 ], [ -0.05003805, 51.51061035 ], [ -0.04963434, 51.51088867 ], [ -0.04915511, 51.51097684 ], [ -0.04836288, 51.51102885 ], [ -0.04818068, 51.51094298 ], [ -0.04780463, 51.51109332 ], [ -0.04739864, 51.5101827 ], [ -0.04703046, 51.51020326 ], [ -0.04688535, 51.50988302 ], [ -0.0475223, 51.50975062 ], [ -0.04948687, 51.50974818 ], [ -0.05238983, 51.50964635 ], [ -0.05259676, 51.50973193 ], [ -0.05242362, 51.50989587 ], [ -0.05214189, 51.50999181 ], [ -0.05161579, 51.5098262 ], [ -0.05163748, 51.51028558 ], [ -0.05176561, 51.51040691 ], [ -0.05177799, 51.51066604 ], [ -0.05207715, 51.51091292 ], [ -0.05197617, 51.51118506 ], [ -0.05203246, 51.51132991 ], [ -0.05169283, 51.51164552 ], [ -0.05196569, 51.51166804 ], [ -0.05190906, 51.51194956 ], [ -0.05098817, 51.51198956 ], [ -0.05101043, 51.51142572 ], [ -0.05082783, 51.5113739 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 95, "LSOA11CD": "E01004303", "LSOA11NM": "Tower Hamlets 025D", "MSOA11CD": "E02000888", "MSOA11NM": "Tower Hamlets 025", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2362, "HHOLDRES": 2362, "COMESTRES": 0, "POPDEN": 106.500000, "HHOLDS": 967, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.06099978, 51.50939045, -0.05452523, 51.51259258 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05460433, 51.51046786 ], [ -0.05452523, 51.50961078 ], [ -0.05495655, 51.50961408 ], [ -0.05526888, 51.50954204 ], [ -0.05681508, 51.50967535 ], [ -0.05750386, 51.50966937 ], [ -0.05815262, 51.50962138 ], [ -0.06023201, 51.50941427 ], [ -0.0604929, 51.50939045 ], [ -0.06099978, 51.51105554 ], [ -0.06046198, 51.51109344 ], [ -0.05998847, 51.51137646 ], [ -0.05949334, 51.51146723 ], [ -0.05961067, 51.51168448 ], [ -0.05799276, 51.51175491 ], [ -0.05804305, 51.51221585 ], [ -0.05794325, 51.51237967 ], [ -0.05718483, 51.51239098 ], [ -0.05721713, 51.51255552 ], [ -0.05673996, 51.51259258 ], [ -0.05662806, 51.51183533 ], [ -0.05695671, 51.51159281 ], [ -0.05718469, 51.51150824 ], [ -0.05713766, 51.51107939 ], [ -0.05621374, 51.51107306 ], [ -0.05663845, 51.51052845 ], [ -0.05623619, 51.51040285 ], [ -0.05614955, 51.51024365 ], [ -0.05627153, 51.51003601 ], [ -0.05596887, 51.50985509 ], [ -0.05558265, 51.51001705 ], [ -0.05556877, 51.51075126 ], [ -0.05497491, 51.51071426 ], [ -0.05525738, 51.51004057 ], [ -0.05508893, 51.50999297 ], [ -0.05460433, 51.51046786 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 96, "LSOA11CD": "E01004303", "LSOA11NM": "Tower Hamlets 025D", "MSOA11CD": "E02000888", "MSOA11NM": "Tower Hamlets 025", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2362, "HHOLDRES": 2362, "COMESTRES": 0, "POPDEN": 106.500000, "HHOLDS": 967, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.05718469, 51.50985509, -0.05302589, 51.5129813 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05361627, 51.51182967 ], [ -0.05329343, 51.5116836 ], [ -0.05302589, 51.51139997 ], [ -0.05317132, 51.5107708 ], [ -0.05361624, 51.51081416 ], [ -0.05465723, 51.51104096 ], [ -0.05460433, 51.51046786 ], [ -0.05508893, 51.50999297 ], [ -0.05525738, 51.51004057 ], [ -0.05497491, 51.51071426 ], [ -0.05556877, 51.51075126 ], [ -0.05558265, 51.51001705 ], [ -0.05596887, 51.50985509 ], [ -0.05627153, 51.51003601 ], [ -0.05614955, 51.51024365 ], [ -0.05623619, 51.51040285 ], [ -0.05663845, 51.51052845 ], [ -0.05621374, 51.51107306 ], [ -0.05713766, 51.51107939 ], [ -0.05718469, 51.51150824 ], [ -0.05695671, 51.51159281 ], [ -0.05662806, 51.51183533 ], [ -0.05673996, 51.51259258 ], [ -0.05685421, 51.51296241 ], [ -0.05631984, 51.5129813 ], [ -0.05623689, 51.51289899 ], [ -0.05537714, 51.5128785 ], [ -0.05543163, 51.5120296 ], [ -0.05522839, 51.5120024 ], [ -0.05362251, 51.51201929 ], [ -0.05361627, 51.51182967 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 97, "LSOA11CD": "E01004289", "LSOA11NM": "Tower Hamlets 016C", "MSOA11CD": "E02000879", "MSOA11NM": "Tower Hamlets 016", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1844, "HHOLDRES": 1844, "COMESTRES": 0, "POPDEN": 175.800000, "HHOLDS": 670, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.05526888, 51.50744273, -0.0420776, 51.51311823 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04464855, 51.5081273 ], [ -0.04547585, 51.50787876 ], [ -0.04637717, 51.50744273 ], [ -0.05131691, 51.5080437 ], [ -0.05226485, 51.50805468 ], [ -0.05390565, 51.50812365 ], [ -0.05506901, 51.50806763 ], [ -0.05526888, 51.50954204 ], [ -0.05495655, 51.50961408 ], [ -0.05452523, 51.50961078 ], [ -0.05460433, 51.51046786 ], [ -0.05465723, 51.51104096 ], [ -0.05361624, 51.51081416 ], [ -0.05317132, 51.5107708 ], [ -0.05302589, 51.51139997 ], [ -0.05329343, 51.5116836 ], [ -0.05361627, 51.51182967 ], [ -0.05303015, 51.51182829 ], [ -0.05302067, 51.51191027 ], [ -0.05190906, 51.51194956 ], [ -0.05196569, 51.51166804 ], [ -0.05169283, 51.51164552 ], [ -0.05203246, 51.51132991 ], [ -0.05197617, 51.51118506 ], [ -0.05207715, 51.51091292 ], [ -0.05177799, 51.51066604 ], [ -0.05176561, 51.51040691 ], [ -0.05163748, 51.51028558 ], [ -0.05161579, 51.5098262 ], [ -0.05214189, 51.50999181 ], [ -0.05242362, 51.50989587 ], [ -0.05259676, 51.50973193 ], [ -0.05238983, 51.50964635 ], [ -0.04948687, 51.50974818 ], [ -0.0475223, 51.50975062 ], [ -0.04688535, 51.50988302 ], [ -0.04703046, 51.51020326 ], [ -0.04739864, 51.5101827 ], [ -0.04780463, 51.51109332 ], [ -0.04789716, 51.51129755 ], [ -0.04693238, 51.51141346 ], [ -0.04626964, 51.51143755 ], [ -0.04621717, 51.51161758 ], [ -0.04658483, 51.51178918 ], [ -0.04659132, 51.51197432 ], [ -0.04604253, 51.51200115 ], [ -0.04510678, 51.51197657 ], [ -0.04513987, 51.51274997 ], [ -0.04432215, 51.51261553 ], [ -0.04432159, 51.51311749 ], [ -0.04368871, 51.51311823 ], [ -0.04368432, 51.5124168 ], [ -0.0430037, 51.51240328 ], [ -0.0430544, 51.51211319 ], [ -0.04289106, 51.51155291 ], [ -0.04213085, 51.51146828 ], [ -0.0420776, 51.51069401 ], [ -0.04544026, 51.51024651 ], [ -0.04545332, 51.51020897 ], [ -0.04482406, 51.50808071 ], [ -0.04464855, 51.5081273 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 98, "LSOA11CD": "E01004326", "LSOA11NM": "Tower Hamlets 017D", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1444, "HHOLDRES": 1438, "COMESTRES": 6, "POPDEN": 172.500000, "HHOLDS": 623, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.0618785, 51.51105554, -0.056718, 51.51468089 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05673996, 51.51259258 ], [ -0.05721713, 51.51255552 ], [ -0.05718483, 51.51239098 ], [ -0.05794325, 51.51237967 ], [ -0.05804305, 51.51221585 ], [ -0.05799276, 51.51175491 ], [ -0.05961067, 51.51168448 ], [ -0.05949334, 51.51146723 ], [ -0.05998847, 51.51137646 ], [ -0.06046198, 51.51109344 ], [ -0.06099978, 51.51105554 ], [ -0.06109723, 51.51149126 ], [ -0.06119719, 51.51184422 ], [ -0.0618785, 51.51468089 ], [ -0.0602905, 51.5146352 ], [ -0.05809402, 51.51451501 ], [ -0.056718, 51.51438539 ], [ -0.05689514, 51.51296505 ], [ -0.05685421, 51.51296241 ], [ -0.05673996, 51.51259258 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 99, "LSOA11CD": "E01004289", "LSOA11NM": "Tower Hamlets 016C", "MSOA11CD": "E02000879", "MSOA11NM": "Tower Hamlets 016", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1844, "HHOLDRES": 1844, "COMESTRES": 0, "POPDEN": 175.800000, "HHOLDS": 670, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.05172138, 51.51061035, -0.04432159, 51.51391936 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04432159, 51.51311749 ], [ -0.04432215, 51.51261553 ], [ -0.04513987, 51.51274997 ], [ -0.04510678, 51.51197657 ], [ -0.04604253, 51.51200115 ], [ -0.04659132, 51.51197432 ], [ -0.04658483, 51.51178918 ], [ -0.04621717, 51.51161758 ], [ -0.04626964, 51.51143755 ], [ -0.04693238, 51.51141346 ], [ -0.04789716, 51.51129755 ], [ -0.04780463, 51.51109332 ], [ -0.04818068, 51.51094298 ], [ -0.04836288, 51.51102885 ], [ -0.04915511, 51.51097684 ], [ -0.04963434, 51.51088867 ], [ -0.05003805, 51.51061035 ], [ -0.05033862, 51.51069392 ], [ -0.05023629, 51.51137766 ], [ -0.05077129, 51.51132792 ], [ -0.05082783, 51.5113739 ], [ -0.05063923, 51.51172151 ], [ -0.05035366, 51.51201712 ], [ -0.04995706, 51.51205289 ], [ -0.04984527, 51.51257404 ], [ -0.05008837, 51.51280528 ], [ -0.05082426, 51.51309697 ], [ -0.05097564, 51.51294504 ], [ -0.05172138, 51.51295144 ], [ -0.0515536, 51.51391936 ], [ -0.0494567, 51.51356752 ], [ -0.04777136, 51.51330018 ], [ -0.04679263, 51.5131643 ], [ -0.04561509, 51.51310632 ], [ -0.04432159, 51.51311749 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 100, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07449591, 51.51638603, -0.06803436, 51.52194333 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0692243, 51.52014017 ], [ -0.06922583, 51.51997505 ], [ -0.06939494, 51.51972604 ], [ -0.06941205, 51.51932164 ], [ -0.06925725, 51.51886373 ], [ -0.06881974, 51.5188036 ], [ -0.06855294, 51.51857796 ], [ -0.06866028, 51.51839869 ], [ -0.06846854, 51.51814018 ], [ -0.06819196, 51.51819728 ], [ -0.06803436, 51.51781515 ], [ -0.06867687, 51.5176189 ], [ -0.07050885, 51.51724438 ], [ -0.07035724, 51.51708002 ], [ -0.06990131, 51.51638603 ], [ -0.07023523, 51.51644886 ], [ -0.07070282, 51.51645465 ], [ -0.07134049, 51.51711954 ], [ -0.07148073, 51.5170985 ], [ -0.07155693, 51.5173191 ], [ -0.07115482, 51.51739221 ], [ -0.0709412, 51.51766184 ], [ -0.07109798, 51.51781391 ], [ -0.07156561, 51.51788267 ], [ -0.07162508, 51.51811705 ], [ -0.07198769, 51.51811275 ], [ -0.07140541, 51.51841822 ], [ -0.07162379, 51.51879507 ], [ -0.07267789, 51.51881822 ], [ -0.07290011, 51.51878176 ], [ -0.07360814, 51.51889506 ], [ -0.07402713, 51.51889157 ], [ -0.07428827, 51.51904563 ], [ -0.07449591, 51.51904023 ], [ -0.07446445, 51.51943118 ], [ -0.07413221, 51.51943258 ], [ -0.0741379, 51.51964583 ], [ -0.07390476, 51.51973299 ], [ -0.07395348, 51.52024345 ], [ -0.07336372, 51.52025675 ], [ -0.07300185, 51.52003349 ], [ -0.07249739, 51.51994531 ], [ -0.07225881, 51.5199906 ], [ -0.0721813, 51.51971801 ], [ -0.07183131, 51.51972241 ], [ -0.0718664, 51.52004662 ], [ -0.07183452, 51.52100717 ], [ -0.0716948, 51.52194333 ], [ -0.07020751, 51.52181504 ], [ -0.06905164, 51.52173618 ], [ -0.06914613, 51.52083704 ], [ -0.06898567, 51.52083106 ], [ -0.06901231, 51.52055696 ], [ -0.0692243, 51.52014017 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 101, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07940911, 51.51584128, -0.07140541, 51.52215704 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07616796, 51.52209804 ], [ -0.07530145, 51.52207201 ], [ -0.07308724, 51.52206404 ], [ -0.0716948, 51.52194333 ], [ -0.07183452, 51.52100717 ], [ -0.0718664, 51.52004662 ], [ -0.07183131, 51.51972241 ], [ -0.0721813, 51.51971801 ], [ -0.07225881, 51.5199906 ], [ -0.07249739, 51.51994531 ], [ -0.07300185, 51.52003349 ], [ -0.07336372, 51.52025675 ], [ -0.07395348, 51.52024345 ], [ -0.07390476, 51.51973299 ], [ -0.0741379, 51.51964583 ], [ -0.07413221, 51.51943258 ], [ -0.07446445, 51.51943118 ], [ -0.07449591, 51.51904023 ], [ -0.07428827, 51.51904563 ], [ -0.07402713, 51.51889157 ], [ -0.07360814, 51.51889506 ], [ -0.07290011, 51.51878176 ], [ -0.07267789, 51.51881822 ], [ -0.07162379, 51.51879507 ], [ -0.07140541, 51.51841822 ], [ -0.07198769, 51.51811275 ], [ -0.07273684, 51.51807238 ], [ -0.07284109, 51.51799316 ], [ -0.07277287, 51.51756038 ], [ -0.07283277, 51.51750741 ], [ -0.07368286, 51.5174586 ], [ -0.07427276, 51.51822351 ], [ -0.07485779, 51.51811755 ], [ -0.07508112, 51.51824556 ], [ -0.07515935, 51.51799899 ], [ -0.07557173, 51.5180052 ], [ -0.07569747, 51.51781477 ], [ -0.07608197, 51.51770465 ], [ -0.07550808, 51.51695782 ], [ -0.07603267, 51.51682255 ], [ -0.07564168, 51.51619329 ], [ -0.0753993, 51.51599101 ], [ -0.07589755, 51.51584128 ], [ -0.0764146, 51.51620311 ], [ -0.07689741, 51.51665328 ], [ -0.07738336, 51.51739241 ], [ -0.07766562, 51.51792044 ], [ -0.07812586, 51.51841486 ], [ -0.07802792, 51.51843161 ], [ -0.07806251, 51.51891377 ], [ -0.07940911, 51.51879096 ], [ -0.07915293, 51.51939813 ], [ -0.07870954, 51.52098555 ], [ -0.07821666, 51.52180002 ], [ -0.07669884, 51.52215704 ], [ -0.07643425, 51.52195796 ], [ -0.07616796, 51.52209804 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 102, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.0692243, 51.51818585, -0.06358474, 51.52173618 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06358474, 51.51990936 ], [ -0.06397787, 51.5199893 ], [ -0.06456384, 51.52027705 ], [ -0.06467208, 51.52045388 ], [ -0.06508565, 51.52043541 ], [ -0.06563789, 51.52019872 ], [ -0.06555424, 51.51994679 ], [ -0.06523193, 51.52010926 ], [ -0.06481909, 51.51987994 ], [ -0.06467607, 51.51972543 ], [ -0.06490015, 51.5195947 ], [ -0.06487026, 51.51907975 ], [ -0.06543955, 51.51884251 ], [ -0.06518106, 51.51859164 ], [ -0.06489006, 51.51842264 ], [ -0.06533164, 51.51818585 ], [ -0.0658649, 51.51866967 ], [ -0.06650634, 51.5183898 ], [ -0.06630291, 51.51886739 ], [ -0.06667546, 51.51908556 ], [ -0.06684683, 51.51897084 ], [ -0.0673644, 51.51896192 ], [ -0.0678163, 51.51909144 ], [ -0.06800454, 51.51954127 ], [ -0.06778998, 51.51960505 ], [ -0.0677815, 51.51995139 ], [ -0.06736007, 51.52021772 ], [ -0.0673964, 51.52028664 ], [ -0.06860275, 51.52041002 ], [ -0.06866591, 51.52010972 ], [ -0.0692243, 51.52014017 ], [ -0.06901231, 51.52055696 ], [ -0.06898567, 51.52083106 ], [ -0.06914613, 51.52083704 ], [ -0.06905164, 51.52173618 ], [ -0.06571728, 51.52151513 ], [ -0.06428795, 51.52148327 ], [ -0.06385088, 51.5204024 ], [ -0.06358474, 51.51990936 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 103, "LSOA11CD": "E01004205", "LSOA11NM": "Tower Hamlets 013A", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2106, "HHOLDRES": 2106, "COMESTRES": 0, "POPDEN": 155.900000, "HHOLDS": 688, "AVHHOLDSZ": 3.100000 }, "bbox": [ -0.07344611, 51.51481966, -0.06273078, 51.52045388 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06358474, 51.51990936 ], [ -0.06336881, 51.51958327 ], [ -0.06312106, 51.51907458 ], [ -0.06273078, 51.5183705 ], [ -0.06291557, 51.51832743 ], [ -0.06422053, 51.51799549 ], [ -0.06617809, 51.51744353 ], [ -0.06703688, 51.51716065 ], [ -0.0678605, 51.51681451 ], [ -0.06889211, 51.51632159 ], [ -0.06972151, 51.51596569 ], [ -0.07192566, 51.51514967 ], [ -0.07280489, 51.51481966 ], [ -0.07268428, 51.51487908 ], [ -0.07344611, 51.51561102 ], [ -0.07239618, 51.51589952 ], [ -0.07222515, 51.51570496 ], [ -0.07192724, 51.51615987 ], [ -0.07163063, 51.51618265 ], [ -0.0713379, 51.51630061 ], [ -0.07070282, 51.51645465 ], [ -0.07023523, 51.51644886 ], [ -0.06990131, 51.51638603 ], [ -0.07035724, 51.51708002 ], [ -0.07050885, 51.51724438 ], [ -0.06867687, 51.5176189 ], [ -0.06803436, 51.51781515 ], [ -0.06819196, 51.51819728 ], [ -0.06846854, 51.51814018 ], [ -0.06866028, 51.51839869 ], [ -0.06855294, 51.51857796 ], [ -0.06881974, 51.5188036 ], [ -0.06925725, 51.51886373 ], [ -0.06941205, 51.51932164 ], [ -0.06939494, 51.51972604 ], [ -0.06922583, 51.51997505 ], [ -0.0692243, 51.52014017 ], [ -0.06866591, 51.52010972 ], [ -0.06860275, 51.52041002 ], [ -0.0673964, 51.52028664 ], [ -0.06736007, 51.52021772 ], [ -0.0677815, 51.51995139 ], [ -0.06778998, 51.51960505 ], [ -0.06800454, 51.51954127 ], [ -0.0678163, 51.51909144 ], [ -0.0673644, 51.51896192 ], [ -0.06684683, 51.51897084 ], [ -0.06667546, 51.51908556 ], [ -0.06630291, 51.51886739 ], [ -0.06650634, 51.5183898 ], [ -0.0658649, 51.51866967 ], [ -0.06533164, 51.51818585 ], [ -0.06489006, 51.51842264 ], [ -0.06518106, 51.51859164 ], [ -0.06543955, 51.51884251 ], [ -0.06487026, 51.51907975 ], [ -0.06490015, 51.5195947 ], [ -0.06467607, 51.51972543 ], [ -0.06481909, 51.51987994 ], [ -0.06523193, 51.52010926 ], [ -0.06555424, 51.51994679 ], [ -0.06563789, 51.52019872 ], [ -0.06508565, 51.52043541 ], [ -0.06467208, 51.52045388 ], [ -0.06456384, 51.52027705 ], [ -0.06397787, 51.5199893 ], [ -0.06358474, 51.51990936 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 104, "LSOA11CD": "E01004310", "LSOA11NM": "Tower Hamlets 015E", "MSOA11CD": "E02000878", "MSOA11NM": "Tower Hamlets 015", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1971, "HHOLDRES": 1893, "COMESTRES": 78, "POPDEN": 214.500000, "HHOLDS": 793, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.07608197, 51.51439921, -0.07070282, 51.51824556 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07198769, 51.51811275 ], [ -0.07162508, 51.51811705 ], [ -0.07156561, 51.51788267 ], [ -0.07109798, 51.51781391 ], [ -0.0709412, 51.51766184 ], [ -0.07115482, 51.51739221 ], [ -0.07155693, 51.5173191 ], [ -0.07148073, 51.5170985 ], [ -0.07134049, 51.51711954 ], [ -0.07070282, 51.51645465 ], [ -0.0713379, 51.51630061 ], [ -0.07163063, 51.51618265 ], [ -0.07192724, 51.51615987 ], [ -0.07222515, 51.51570496 ], [ -0.07239618, 51.51589952 ], [ -0.07344611, 51.51561102 ], [ -0.07268428, 51.51487908 ], [ -0.07280489, 51.51481966 ], [ -0.07394854, 51.51439921 ], [ -0.07442254, 51.51473678 ], [ -0.07512482, 51.51530051 ], [ -0.07589755, 51.51584128 ], [ -0.0753993, 51.51599101 ], [ -0.07564168, 51.51619329 ], [ -0.07603267, 51.51682255 ], [ -0.07550808, 51.51695782 ], [ -0.07608197, 51.51770465 ], [ -0.07569747, 51.51781477 ], [ -0.07557173, 51.5180052 ], [ -0.07515935, 51.51799899 ], [ -0.07508112, 51.51824556 ], [ -0.07485779, 51.51811755 ], [ -0.07427276, 51.51822351 ], [ -0.07368286, 51.5174586 ], [ -0.07283277, 51.51750741 ], [ -0.07277287, 51.51756038 ], [ -0.07284109, 51.51799316 ], [ -0.07273684, 51.51807238 ], [ -0.07198769, 51.51811275 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 105, "LSOA11CD": "E01004315", "LSOA11NM": "Tower Hamlets 006C", "MSOA11CD": "E02000869", "MSOA11NM": "Tower Hamlets 006", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1628, "HHOLDRES": 1628, "COMESTRES": 0, "POPDEN": 170.300000, "HHOLDS": 718, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07723227, 51.52674909, -0.07026665, 51.53006928 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07118835, 51.52999118 ], [ -0.07026665, 51.52876912 ], [ -0.071017, 51.52841276 ], [ -0.07127747, 51.52839006 ], [ -0.07117209, 51.52815452 ], [ -0.07115563, 51.52806497 ], [ -0.07148859, 51.52804253 ], [ -0.07175208, 51.52790433 ], [ -0.07184507, 51.52792278 ], [ -0.0719785, 51.528244 ], [ -0.07226675, 51.52804779 ], [ -0.07289201, 51.52795324 ], [ -0.07269236, 51.52761975 ], [ -0.07342042, 51.52745992 ], [ -0.07352412, 51.52752178 ], [ -0.07387892, 51.52737518 ], [ -0.07383996, 51.52721715 ], [ -0.07437871, 51.52709312 ], [ -0.07447552, 51.52678214 ], [ -0.07487524, 51.52677148 ], [ -0.07501691, 51.52689575 ], [ -0.07551124, 51.52674909 ], [ -0.07565242, 51.52685515 ], [ -0.07603226, 51.52686713 ], [ -0.07629709, 51.52708657 ], [ -0.07723227, 51.52724345 ], [ -0.07633035, 51.5278215 ], [ -0.07566154, 51.52833941 ], [ -0.07529721, 51.52875244 ], [ -0.07485822, 51.52943345 ], [ -0.0741809, 51.52928309 ], [ -0.07353417, 51.52978406 ], [ -0.07320723, 51.52943493 ], [ -0.07300723, 51.52956109 ], [ -0.07274292, 51.52957337 ], [ -0.07251812, 51.52977749 ], [ -0.07214466, 51.52979 ], [ -0.07126286, 51.53006928 ], [ -0.07118835, 51.52999118 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 106, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07175208, 51.52467832, -0.06609028, 51.52842457 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06710324, 51.52788969 ], [ -0.06618722, 51.52807243 ], [ -0.06609028, 51.52777796 ], [ -0.06650511, 51.52754392 ], [ -0.06702099, 51.52763084 ], [ -0.06678024, 51.52697528 ], [ -0.06723318, 51.52699732 ], [ -0.06730184, 51.5269387 ], [ -0.06828893, 51.5268357 ], [ -0.0685629, 51.52653486 ], [ -0.0682414, 51.52596462 ], [ -0.06802638, 51.52600881 ], [ -0.06794818, 51.52574799 ], [ -0.06790476, 51.52554201 ], [ -0.06827238, 51.52553746 ], [ -0.06850496, 51.52537084 ], [ -0.06829926, 51.52500848 ], [ -0.06778292, 51.52502907 ], [ -0.06777835, 51.52492042 ], [ -0.06884994, 51.524771 ], [ -0.06894508, 51.52490746 ], [ -0.06943365, 51.52480403 ], [ -0.06958107, 51.52467832 ], [ -0.06988815, 51.52478091 ], [ -0.07008661, 51.52493959 ], [ -0.06953041, 51.52504299 ], [ -0.06955117, 51.52533787 ], [ -0.06953024, 51.52562603 ], [ -0.06921263, 51.52573919 ], [ -0.069341, 51.5259251 ], [ -0.06997353, 51.5260271 ], [ -0.07035329, 51.52603531 ], [ -0.07057057, 51.52635506 ], [ -0.07114035, 51.52685904 ], [ -0.07119228, 51.52699478 ], [ -0.07084347, 51.52706099 ], [ -0.07104691, 51.52773594 ], [ -0.07175208, 51.52790433 ], [ -0.07148859, 51.52804253 ], [ -0.07115563, 51.52806497 ], [ -0.07117209, 51.52815452 ], [ -0.07056806, 51.5281687 ], [ -0.07010901, 51.52798029 ], [ -0.06984001, 51.52811397 ], [ -0.06932589, 51.528113 ], [ -0.06909614, 51.52787704 ], [ -0.06932183, 51.52775583 ], [ -0.06802872, 51.527824 ], [ -0.06819357, 51.52835729 ], [ -0.06749265, 51.52842457 ], [ -0.06730789, 51.52786464 ], [ -0.06710324, 51.52788969 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 107, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.0685629, 51.5231928, -0.06393923, 51.52867401 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06499256, 51.52830505 ], [ -0.06519131, 51.52822659 ], [ -0.06479401, 51.5269804 ], [ -0.06461538, 51.5264028 ], [ -0.06399817, 51.52427902 ], [ -0.06393923, 51.52373984 ], [ -0.06407867, 51.5231928 ], [ -0.0647256, 51.52332471 ], [ -0.06430657, 51.52380581 ], [ -0.06483652, 51.5238865 ], [ -0.06479628, 51.52415562 ], [ -0.0649584, 51.52475182 ], [ -0.06565232, 51.5246887 ], [ -0.06586676, 51.52497269 ], [ -0.06584859, 51.52523034 ], [ -0.06665276, 51.52509994 ], [ -0.06708973, 51.52520566 ], [ -0.06693588, 51.52550923 ], [ -0.06733226, 51.52569317 ], [ -0.06794818, 51.52574799 ], [ -0.06802638, 51.52600881 ], [ -0.0682414, 51.52596462 ], [ -0.0685629, 51.52653486 ], [ -0.06828893, 51.5268357 ], [ -0.06730184, 51.5269387 ], [ -0.06723318, 51.52699732 ], [ -0.06678024, 51.52697528 ], [ -0.06702099, 51.52763084 ], [ -0.06650511, 51.52754392 ], [ -0.06609028, 51.52777796 ], [ -0.06618722, 51.52807243 ], [ -0.06710324, 51.52788969 ], [ -0.06729575, 51.52845041 ], [ -0.06558503, 51.52867401 ], [ -0.06534399, 51.52823838 ], [ -0.06499256, 51.52830505 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 108, "LSOA11CD": "E01004313", "LSOA11NM": "Tower Hamlets 009B", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2043, "HHOLDRES": 2043, "COMESTRES": 0, "POPDEN": 248.800000, "HHOLDS": 812, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.07127747, 51.52775583, -0.06499256, 51.53101505 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06499256, 51.52830505 ], [ -0.06534399, 51.52823838 ], [ -0.06558503, 51.52867401 ], [ -0.06729575, 51.52845041 ], [ -0.06710324, 51.52788969 ], [ -0.06730789, 51.52786464 ], [ -0.06749265, 51.52842457 ], [ -0.06819357, 51.52835729 ], [ -0.06802872, 51.527824 ], [ -0.06932183, 51.52775583 ], [ -0.06909614, 51.52787704 ], [ -0.06932589, 51.528113 ], [ -0.06984001, 51.52811397 ], [ -0.07010901, 51.52798029 ], [ -0.07056806, 51.5281687 ], [ -0.07117209, 51.52815452 ], [ -0.07127747, 51.52839006 ], [ -0.071017, 51.52841276 ], [ -0.07026665, 51.52876912 ], [ -0.07118835, 51.52999118 ], [ -0.07058847, 51.53002968 ], [ -0.07056959, 51.52989432 ], [ -0.06938402, 51.53002973 ], [ -0.0692998, 51.5298191 ], [ -0.06896339, 51.53007698 ], [ -0.06841069, 51.53013347 ], [ -0.06845207, 51.53030033 ], [ -0.06801764, 51.53042305 ], [ -0.06799612, 51.53029647 ], [ -0.06844083, 51.52999838 ], [ -0.06829679, 51.52987487 ], [ -0.06787582, 51.5299976 ], [ -0.06734623, 51.53001537 ], [ -0.067047, 51.53023715 ], [ -0.06656071, 51.53049134 ], [ -0.06628183, 51.53089101 ], [ -0.06591045, 51.53101505 ], [ -0.06542472, 51.52977733 ], [ -0.06542982, 51.52955049 ], [ -0.06499256, 51.52830505 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 109, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07661563, 51.52464579, -0.06921263, 51.528244 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07175208, 51.52790433 ], [ -0.07104691, 51.52773594 ], [ -0.07084347, 51.52706099 ], [ -0.07119228, 51.52699478 ], [ -0.07114035, 51.52685904 ], [ -0.07057057, 51.52635506 ], [ -0.07035329, 51.52603531 ], [ -0.06997353, 51.5260271 ], [ -0.069341, 51.5259251 ], [ -0.06921263, 51.52573919 ], [ -0.06953024, 51.52562603 ], [ -0.06955117, 51.52533787 ], [ -0.0695794, 51.52517008 ], [ -0.06992499, 51.52529051 ], [ -0.07008665, 51.52549689 ], [ -0.07027608, 51.52547792 ], [ -0.07193664, 51.52473186 ], [ -0.07271875, 51.52464579 ], [ -0.07348001, 51.5266416 ], [ -0.07381261, 51.52659629 ], [ -0.07427775, 51.52644057 ], [ -0.07415231, 51.52621961 ], [ -0.07373955, 51.52633324 ], [ -0.0736047, 51.52585637 ], [ -0.07384841, 51.52587734 ], [ -0.07370478, 51.52553429 ], [ -0.07391306, 51.5252401 ], [ -0.07458503, 51.52529713 ], [ -0.07477882, 51.5257048 ], [ -0.07506694, 51.52570953 ], [ -0.07518346, 51.5254839 ], [ -0.07557147, 51.52571746 ], [ -0.07654607, 51.52532434 ], [ -0.07661563, 51.52633366 ], [ -0.07633658, 51.52681863 ], [ -0.07629709, 51.52708657 ], [ -0.07603226, 51.52686713 ], [ -0.07565242, 51.52685515 ], [ -0.07551124, 51.52674909 ], [ -0.07501691, 51.52689575 ], [ -0.07487524, 51.52677148 ], [ -0.07447552, 51.52678214 ], [ -0.07437871, 51.52709312 ], [ -0.07383996, 51.52721715 ], [ -0.07387892, 51.52737518 ], [ -0.07352412, 51.52752178 ], [ -0.07342042, 51.52745992 ], [ -0.07269236, 51.52761975 ], [ -0.07289201, 51.52795324 ], [ -0.07226675, 51.52804779 ], [ -0.0719785, 51.528244 ], [ -0.07184507, 51.52792278 ], [ -0.07175208, 51.52790433 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 110, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07654607, 51.52423376, -0.07271875, 51.5266416 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07271875, 51.52464579 ], [ -0.07393834, 51.52444102 ], [ -0.07549467, 51.52433591 ], [ -0.07592824, 51.52426473 ], [ -0.07642211, 51.52423376 ], [ -0.07654607, 51.52532434 ], [ -0.07557147, 51.52571746 ], [ -0.07518346, 51.5254839 ], [ -0.07506694, 51.52570953 ], [ -0.07477882, 51.5257048 ], [ -0.07458503, 51.52529713 ], [ -0.07391306, 51.5252401 ], [ -0.07370478, 51.52553429 ], [ -0.07384841, 51.52587734 ], [ -0.0736047, 51.52585637 ], [ -0.07373955, 51.52633324 ], [ -0.07415231, 51.52621961 ], [ -0.07427775, 51.52644057 ], [ -0.07381261, 51.52659629 ], [ -0.07348001, 51.5266416 ], [ -0.07271875, 51.52464579 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 111, "LSOA11CD": "E01004317", "LSOA11NM": "Tower Hamlets 009D", "MSOA11CD": "E02000872", "MSOA11NM": "Tower Hamlets 009", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2706, "HHOLDRES": 2689, "COMESTRES": 17, "POPDEN": 100.000000, "HHOLDS": 1193, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07616796, 51.52148327, -0.06407867, 51.52574799 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06794818, 51.52574799 ], [ -0.06733226, 51.52569317 ], [ -0.06693588, 51.52550923 ], [ -0.06708973, 51.52520566 ], [ -0.06665276, 51.52509994 ], [ -0.06584859, 51.52523034 ], [ -0.06586676, 51.52497269 ], [ -0.06565232, 51.5246887 ], [ -0.0649584, 51.52475182 ], [ -0.06479628, 51.52415562 ], [ -0.06483652, 51.5238865 ], [ -0.06430657, 51.52380581 ], [ -0.0647256, 51.52332471 ], [ -0.06407867, 51.5231928 ], [ -0.06423226, 51.52262611 ], [ -0.06436593, 51.52174717 ], [ -0.06428795, 51.52148327 ], [ -0.06571728, 51.52151513 ], [ -0.06905164, 51.52173618 ], [ -0.07020751, 51.52181504 ], [ -0.0716948, 51.52194333 ], [ -0.07308724, 51.52206404 ], [ -0.07530145, 51.52207201 ], [ -0.07616796, 51.52209804 ], [ -0.07584384, 51.52284095 ], [ -0.07569839, 51.52353381 ], [ -0.07592824, 51.52426473 ], [ -0.07549467, 51.52433591 ], [ -0.07393834, 51.52444102 ], [ -0.07271875, 51.52464579 ], [ -0.07193664, 51.52473186 ], [ -0.07027608, 51.52547792 ], [ -0.07008665, 51.52549689 ], [ -0.06992499, 51.52529051 ], [ -0.0695794, 51.52517008 ], [ -0.06955117, 51.52533787 ], [ -0.06953041, 51.52504299 ], [ -0.07008661, 51.52493959 ], [ -0.06988815, 51.52478091 ], [ -0.06958107, 51.52467832 ], [ -0.06943365, 51.52480403 ], [ -0.06894508, 51.52490746 ], [ -0.06884994, 51.524771 ], [ -0.06777835, 51.52492042 ], [ -0.06778292, 51.52502907 ], [ -0.06829926, 51.52500848 ], [ -0.06850496, 51.52537084 ], [ -0.06827238, 51.52553746 ], [ -0.06790476, 51.52554201 ], [ -0.06794818, 51.52574799 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 112, "LSOA11CD": "E01001774", "LSOA11NM": "Hackney 024B", "MSOA11CD": "E02000368", "MSOA11NM": "Hackney 024", "LAD11CD": "E09000012", "LAD11NM": "Hackney", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2095, "HHOLDRES": 2082, "COMESTRES": 13, "POPDEN": 116.600000, "HHOLDS": 875, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.07485822, 51.52928309, -0.06591045, 51.53120434 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07118835, 51.52999118 ], [ -0.07126286, 51.53006928 ], [ -0.07214466, 51.52979 ], [ -0.07251812, 51.52977749 ], [ -0.07274292, 51.52957337 ], [ -0.07300723, 51.52956109 ], [ -0.07320723, 51.52943493 ], [ -0.07353417, 51.52978406 ], [ -0.0741809, 51.52928309 ], [ -0.07485822, 51.52943345 ], [ -0.07462845, 51.52973839 ], [ -0.07435241, 51.52995924 ], [ -0.07375193, 51.53028731 ], [ -0.0727685, 51.5306362 ], [ -0.07224492, 51.53078624 ], [ -0.07161423, 51.53086916 ], [ -0.07050966, 51.53094922 ], [ -0.06923408, 51.53097927 ], [ -0.06797453, 51.53104027 ], [ -0.06629206, 51.53117348 ], [ -0.06598509, 51.53120434 ], [ -0.06591045, 51.53101505 ], [ -0.06628183, 51.53089101 ], [ -0.06656071, 51.53049134 ], [ -0.067047, 51.53023715 ], [ -0.06734623, 51.53001537 ], [ -0.06787582, 51.5299976 ], [ -0.06829679, 51.52987487 ], [ -0.06844083, 51.52999838 ], [ -0.06799612, 51.53029647 ], [ -0.06801764, 51.53042305 ], [ -0.06845207, 51.53030033 ], [ -0.06841069, 51.53013347 ], [ -0.06896339, 51.53007698 ], [ -0.0692998, 51.5298191 ], [ -0.06938402, 51.53002973 ], [ -0.07056959, 51.52989432 ], [ -0.07058847, 51.53002968 ], [ -0.07118835, 51.52999118 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 113, "LSOA11CD": "E01032766", "LSOA11NM": "Tower Hamlets 021E", "MSOA11CD": "E02000884", "MSOA11NM": "Tower Hamlets 021", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1307, "HHOLDRES": 1307, "COMESTRES": 0, "POPDEN": 162.000000, "HHOLDS": 601, "AVHHOLDSZ": 2.200000 }, "bbox": [ -0.06690883, 51.5111302, -0.06109723, 51.51470819 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0618785, 51.51468089 ], [ -0.06119719, 51.51184422 ], [ -0.06109723, 51.51149126 ], [ -0.06380131, 51.51131227 ], [ -0.0648347, 51.51126427 ], [ -0.0663052, 51.51116855 ], [ -0.06686061, 51.5111302 ], [ -0.06690883, 51.51171748 ], [ -0.06629602, 51.5115545 ], [ -0.06645616, 51.51253736 ], [ -0.06667517, 51.51250984 ], [ -0.06673535, 51.51277619 ], [ -0.06604293, 51.51288383 ], [ -0.06537327, 51.51292417 ], [ -0.06542713, 51.51325117 ], [ -0.06585118, 51.5131294 ], [ -0.06587219, 51.51347163 ], [ -0.06542091, 51.5135005 ], [ -0.06547066, 51.51390467 ], [ -0.06524336, 51.51390308 ], [ -0.06511985, 51.51412135 ], [ -0.06481032, 51.51413912 ], [ -0.06470156, 51.51353461 ], [ -0.06419289, 51.51357016 ], [ -0.06417703, 51.51394411 ], [ -0.0636681, 51.51388533 ], [ -0.06367837, 51.51334693 ], [ -0.06295112, 51.51332638 ], [ -0.0627998, 51.51315147 ], [ -0.0634903, 51.51314488 ], [ -0.06348353, 51.51304248 ], [ -0.06258058, 51.51298115 ], [ -0.06188953, 51.51315268 ], [ -0.0618315, 51.51331718 ], [ -0.06248594, 51.51370723 ], [ -0.06231419, 51.51470819 ], [ -0.0618785, 51.51468089 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 114, "LSOA11CD": "E01004322", "LSOA11NM": "Tower Hamlets 017A", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1292, "HHOLDRES": 1160, "COMESTRES": 132, "POPDEN": 91.100000, "HHOLDS": 502, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.06555445, 51.51298115, -0.05911893, 51.51769225 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05919102, 51.51668017 ], [ -0.05926316, 51.51663615 ], [ -0.05911893, 51.51629055 ], [ -0.05977426, 51.51621856 ], [ -0.0595425, 51.51603985 ], [ -0.05948979, 51.51586902 ], [ -0.05971073, 51.51580024 ], [ -0.05956994, 51.515535 ], [ -0.05933308, 51.51541312 ], [ -0.05973624, 51.51534003 ], [ -0.06048864, 51.51527154 ], [ -0.0602905, 51.5146352 ], [ -0.0618785, 51.51468089 ], [ -0.06231419, 51.51470819 ], [ -0.06248594, 51.51370723 ], [ -0.0618315, 51.51331718 ], [ -0.06188953, 51.51315268 ], [ -0.06258058, 51.51298115 ], [ -0.06348353, 51.51304248 ], [ -0.0634903, 51.51314488 ], [ -0.0627998, 51.51315147 ], [ -0.06295112, 51.51332638 ], [ -0.06367837, 51.51334693 ], [ -0.0636681, 51.51388533 ], [ -0.06417703, 51.51394411 ], [ -0.06419289, 51.51357016 ], [ -0.06470156, 51.51353461 ], [ -0.06481032, 51.51413912 ], [ -0.06511985, 51.51412135 ], [ -0.06524336, 51.51390308 ], [ -0.06547066, 51.51390467 ], [ -0.06555445, 51.51477068 ], [ -0.06315406, 51.51474005 ], [ -0.06303617, 51.51475183 ], [ -0.06320917, 51.51566565 ], [ -0.06348381, 51.51563165 ], [ -0.06345471, 51.51520304 ], [ -0.06335492, 51.51499922 ], [ -0.06370574, 51.51500763 ], [ -0.06392407, 51.51515044 ], [ -0.06403323, 51.51535121 ], [ -0.06406576, 51.51572247 ], [ -0.06416187, 51.51587808 ], [ -0.06439872, 51.5159264 ], [ -0.06409763, 51.5161091 ], [ -0.06354639, 51.51605235 ], [ -0.0634857, 51.51592572 ], [ -0.06300812, 51.51594995 ], [ -0.06320383, 51.516602 ], [ -0.06340156, 51.51656935 ], [ -0.06353823, 51.5171115 ], [ -0.06275765, 51.51721464 ], [ -0.06285462, 51.51769225 ], [ -0.06259661, 51.51765193 ], [ -0.06238337, 51.51681365 ], [ -0.06087853, 51.51695064 ], [ -0.06097582, 51.51737491 ], [ -0.05924296, 51.51753779 ], [ -0.0593759, 51.51695661 ], [ -0.05919102, 51.51668017 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 115, "LSOA11CD": "E01004208", "LSOA11NM": "Tower Hamlets 013C", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1976, "HHOLDRES": 1842, "COMESTRES": 134, "POPDEN": 122.100000, "HHOLDS": 788, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.06291557, 51.51668017, -0.05283379, 51.52039948 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05399876, 51.51775612 ], [ -0.05419281, 51.51771469 ], [ -0.05462356, 51.51809833 ], [ -0.05538846, 51.51803329 ], [ -0.05520097, 51.51759403 ], [ -0.05727434, 51.51764639 ], [ -0.05720678, 51.51686289 ], [ -0.05844569, 51.51674881 ], [ -0.05919102, 51.51668017 ], [ -0.0593759, 51.51695661 ], [ -0.05924296, 51.51753779 ], [ -0.06097582, 51.51737491 ], [ -0.06087853, 51.51695064 ], [ -0.06238337, 51.51681365 ], [ -0.06259661, 51.51765193 ], [ -0.06291557, 51.51832743 ], [ -0.06273078, 51.5183705 ], [ -0.06179993, 51.51858851 ], [ -0.05800544, 51.51943457 ], [ -0.05634912, 51.5197805 ], [ -0.05421828, 51.52014757 ], [ -0.05296427, 51.52039948 ], [ -0.05283379, 51.52005475 ], [ -0.05303295, 51.52002777 ], [ -0.05297828, 51.51984282 ], [ -0.05332538, 51.51984895 ], [ -0.05357339, 51.51955236 ], [ -0.05339125, 51.51946817 ], [ -0.0532869, 51.51926488 ], [ -0.05336586, 51.51896417 ], [ -0.05526599, 51.5188292 ], [ -0.05551482, 51.51925642 ], [ -0.05585341, 51.51919658 ], [ -0.0555929, 51.51854478 ], [ -0.05363333, 51.5187407 ], [ -0.05346615, 51.51842955 ], [ -0.05395157, 51.518362 ], [ -0.05385719, 51.5179231 ], [ -0.05399876, 51.51775612 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 116, "LSOA11CD": "E01004322", "LSOA11NM": "Tower Hamlets 017A", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1292, "HHOLDRES": 1160, "COMESTRES": 132, "POPDEN": 91.100000, "HHOLDS": 502, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05852842, 51.515248, -0.05296102, 51.51809833 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05399876, 51.51775612 ], [ -0.05361273, 51.51767965 ], [ -0.05325197, 51.51727668 ], [ -0.05296102, 51.51708271 ], [ -0.05311263, 51.51536979 ], [ -0.05338679, 51.51536666 ], [ -0.05337074, 51.51555828 ], [ -0.05355491, 51.51563328 ], [ -0.05457638, 51.5156772 ], [ -0.05472439, 51.515248 ], [ -0.05545894, 51.51526019 ], [ -0.05560183, 51.51555455 ], [ -0.05597273, 51.51557111 ], [ -0.0559821, 51.51600721 ], [ -0.05644063, 51.51600493 ], [ -0.05684156, 51.51587511 ], [ -0.05714475, 51.51602846 ], [ -0.05715737, 51.51642977 ], [ -0.05780587, 51.51640218 ], [ -0.05806284, 51.51629065 ], [ -0.05852842, 51.51656587 ], [ -0.05844569, 51.51674881 ], [ -0.05720678, 51.51686289 ], [ -0.05727434, 51.51764639 ], [ -0.05520097, 51.51759403 ], [ -0.05538846, 51.51803329 ], [ -0.05462356, 51.51809833 ], [ -0.05419281, 51.51771469 ], [ -0.05399876, 51.51775612 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 117, "LSOA11CD": "E01004322", "LSOA11NM": "Tower Hamlets 017A", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1292, "HHOLDRES": 1160, "COMESTRES": 132, "POPDEN": 91.100000, "HHOLDS": 502, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05585341, 51.51681292, -0.04963771, 51.52005475 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05127757, 51.51929377 ], [ -0.05048272, 51.51924863 ], [ -0.05062064, 51.51876166 ], [ -0.05013369, 51.51868861 ], [ -0.0501833, 51.51841267 ], [ -0.04963771, 51.51838364 ], [ -0.04981922, 51.51681292 ], [ -0.04987515, 51.51681812 ], [ -0.05296018, 51.5170947 ], [ -0.05296102, 51.51708271 ], [ -0.05325197, 51.51727668 ], [ -0.05361273, 51.51767965 ], [ -0.05399876, 51.51775612 ], [ -0.05385719, 51.5179231 ], [ -0.05395157, 51.518362 ], [ -0.05346615, 51.51842955 ], [ -0.05363333, 51.5187407 ], [ -0.0555929, 51.51854478 ], [ -0.05585341, 51.51919658 ], [ -0.05551482, 51.51925642 ], [ -0.05526599, 51.5188292 ], [ -0.05336586, 51.51896417 ], [ -0.0532869, 51.51926488 ], [ -0.05339125, 51.51946817 ], [ -0.05357339, 51.51955236 ], [ -0.05332538, 51.51984895 ], [ -0.05297828, 51.51984282 ], [ -0.05303295, 51.52002777 ], [ -0.05283379, 51.52005475 ], [ -0.05272119, 51.51971958 ], [ -0.05165078, 51.5197226 ], [ -0.05169784, 51.5193166 ], [ -0.05127757, 51.51929377 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 118, "LSOA11CD": "E01004322", "LSOA11NM": "Tower Hamlets 017A", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1292, "HHOLDRES": 1160, "COMESTRES": 132, "POPDEN": 91.100000, "HHOLDS": 502, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.07192566, 51.51438103, -0.06259661, 51.51832743 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06259661, 51.51765193 ], [ -0.06285462, 51.51769225 ], [ -0.06275765, 51.51721464 ], [ -0.06353823, 51.5171115 ], [ -0.06340156, 51.51656935 ], [ -0.06320383, 51.516602 ], [ -0.06300812, 51.51594995 ], [ -0.0634857, 51.51592572 ], [ -0.06354639, 51.51605235 ], [ -0.06409763, 51.5161091 ], [ -0.06439872, 51.5159264 ], [ -0.06416187, 51.51587808 ], [ -0.06406576, 51.51572247 ], [ -0.06403323, 51.51535121 ], [ -0.06392407, 51.51515044 ], [ -0.06370574, 51.51500763 ], [ -0.06335492, 51.51499922 ], [ -0.06345471, 51.51520304 ], [ -0.06348381, 51.51563165 ], [ -0.06320917, 51.51566565 ], [ -0.06303617, 51.51475183 ], [ -0.06315406, 51.51474005 ], [ -0.06555445, 51.51477068 ], [ -0.06636101, 51.51478398 ], [ -0.06766787, 51.51489545 ], [ -0.06796843, 51.51494537 ], [ -0.06917598, 51.51496526 ], [ -0.069628, 51.51438103 ], [ -0.07089149, 51.5148007 ], [ -0.07128115, 51.51465817 ], [ -0.07161811, 51.51452882 ], [ -0.07170298, 51.51490792 ], [ -0.07192566, 51.51514967 ], [ -0.06972151, 51.51596569 ], [ -0.06889211, 51.51632159 ], [ -0.0678605, 51.51681451 ], [ -0.06703688, 51.51716065 ], [ -0.06617809, 51.51744353 ], [ -0.06422053, 51.51799549 ], [ -0.06291557, 51.51832743 ], [ -0.06259661, 51.51765193 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 119, "LSOA11CD": "E01004322", "LSOA11NM": "Tower Hamlets 017A", "MSOA11CD": "E02000880", "MSOA11NM": "Tower Hamlets 017", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1292, "HHOLDRES": 1160, "COMESTRES": 132, "POPDEN": 91.100000, "HHOLDS": 502, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.06048864, 51.51407609, -0.05311263, 51.51674881 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.05311263, 51.51536979 ], [ -0.05322315, 51.51407609 ], [ -0.05491359, 51.51419111 ], [ -0.056718, 51.51438539 ], [ -0.05809402, 51.51451501 ], [ -0.0602905, 51.5146352 ], [ -0.06048864, 51.51527154 ], [ -0.05973624, 51.51534003 ], [ -0.05933308, 51.51541312 ], [ -0.05956994, 51.515535 ], [ -0.05971073, 51.51580024 ], [ -0.05948979, 51.51586902 ], [ -0.0595425, 51.51603985 ], [ -0.05977426, 51.51621856 ], [ -0.05911893, 51.51629055 ], [ -0.05926316, 51.51663615 ], [ -0.05919102, 51.51668017 ], [ -0.05844569, 51.51674881 ], [ -0.05852842, 51.51656587 ], [ -0.05806284, 51.51629065 ], [ -0.05780587, 51.51640218 ], [ -0.05715737, 51.51642977 ], [ -0.05714475, 51.51602846 ], [ -0.05684156, 51.51587511 ], [ -0.05644063, 51.51600493 ], [ -0.0559821, 51.51600721 ], [ -0.05597273, 51.51557111 ], [ -0.05560183, 51.51555455 ], [ -0.05545894, 51.51526019 ], [ -0.05472439, 51.515248 ], [ -0.05457638, 51.5156772 ], [ -0.05355491, 51.51563328 ], [ -0.05337074, 51.51555828 ], [ -0.05338679, 51.51536666 ], [ -0.05311263, 51.51536979 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 120, "LSOA11CD": "E01004235", "LSOA11NM": "Tower Hamlets 008A", "MSOA11CD": "E02000871", "MSOA11NM": "Tower Hamlets 008", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1372, "HHOLDRES": 1372, "COMESTRES": 0, "POPDEN": 345.600000, "HHOLDS": 513, "AVHHOLDSZ": 2.700000 }, "bbox": [ -0.02654337, 51.52808353, -0.01362497, 51.53997001 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01899154, 51.53904899 ], [ -0.01912606, 51.53871518 ], [ -0.01948637, 51.53818016 ], [ -0.0198812, 51.5379502 ], [ -0.02067118, 51.53760734 ], [ -0.0211262, 51.5372983 ], [ -0.02125007, 51.53708133 ], [ -0.02119885, 51.53680731 ], [ -0.02095465, 51.53624638 ], [ -0.02041073, 51.5360285 ], [ -0.01986531, 51.53567952 ], [ -0.01938072, 51.5351336 ], [ -0.01915577, 51.53477262 ], [ -0.01903746, 51.53417668 ], [ -0.01874979, 51.53384864 ], [ -0.01844636, 51.53367672 ], [ -0.01808684, 51.53336419 ], [ -0.01800224, 51.53315424 ], [ -0.01804133, 51.53285575 ], [ -0.01820609, 51.53250683 ], [ -0.01816776, 51.53228979 ], [ -0.01791066, 51.53206779 ], [ -0.01764282, 51.53161587 ], [ -0.01750352, 51.53148284 ], [ -0.01645029, 51.53093896 ], [ -0.01583886, 51.53070098 ], [ -0.0150482, 51.5304611 ], [ -0.01415329, 51.53011111 ], [ -0.01394352, 51.52990001 ], [ -0.01362497, 51.52978615 ], [ -0.01371535, 51.52975439 ], [ -0.01461511, 51.52943814 ], [ -0.01523716, 51.5291831 ], [ -0.01581644, 51.5288752 ], [ -0.01645267, 51.52862517 ], [ -0.01780173, 51.52826377 ], [ -0.0190385, 51.52808353 ], [ -0.01918022, 51.52817658 ], [ -0.01892129, 51.52870356 ], [ -0.01939571, 51.52884844 ], [ -0.01963499, 51.52903753 ], [ -0.01969999, 51.52922337 ], [ -0.01922361, 51.52932931 ], [ -0.01932598, 51.52945042 ], [ -0.01869113, 51.5297554 ], [ -0.01809498, 51.52918412 ], [ -0.0179901, 51.52956098 ], [ -0.01734677, 51.52978893 ], [ -0.01732586, 51.53009132 ], [ -0.01739796, 51.53043654 ], [ -0.01818547, 51.53088623 ], [ -0.0180689, 51.5312506 ], [ -0.01988759, 51.53226566 ], [ -0.02030951, 51.53210274 ], [ -0.02042824, 51.53220585 ], [ -0.02086494, 51.53191232 ], [ -0.02157724, 51.53235258 ], [ -0.02191146, 51.53215511 ], [ -0.02244837, 51.5324746 ], [ -0.02235684, 51.53263198 ], [ -0.02253148, 51.53278203 ], [ -0.02149043, 51.53336109 ], [ -0.02185246, 51.53335709 ], [ -0.02222189, 51.53356228 ], [ -0.02210117, 51.53368615 ], [ -0.02362227, 51.53452114 ], [ -0.02384577, 51.5346738 ], [ -0.02490631, 51.53442082 ], [ -0.02545345, 51.53440159 ], [ -0.02586732, 51.53495463 ], [ -0.02654337, 51.53597193 ], [ -0.02548249, 51.53607872 ], [ -0.02520376, 51.53564659 ], [ -0.02457277, 51.53580543 ], [ -0.0239962, 51.5358125 ], [ -0.02371404, 51.53628527 ], [ -0.02369705, 51.53645584 ], [ -0.02393422, 51.5366397 ], [ -0.02414726, 51.53704797 ], [ -0.02433965, 51.53726704 ], [ -0.02518672, 51.53768598 ], [ -0.02559255, 51.53797159 ], [ -0.02516145, 51.53860282 ], [ -0.02411576, 51.53910679 ], [ -0.02363164, 51.53829827 ], [ -0.02170263, 51.53921899 ], [ -0.02159629, 51.53967583 ], [ -0.02166522, 51.53974893 ], [ -0.02120581, 51.53997001 ], [ -0.02058446, 51.53936735 ], [ -0.02009814, 51.53927015 ], [ -0.02010619, 51.53945284 ], [ -0.01994729, 51.53945915 ], [ -0.01991473, 51.5392335 ], [ -0.01899154, 51.53904899 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 121, "LSOA11CD": "E01004224", "LSOA11NM": "Tower Hamlets 001C", "MSOA11CD": "E02000864", "MSOA11NM": "Tower Hamlets 001", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2000, "HHOLDRES": 2000, "COMESTRES": 0, "POPDEN": 45.600000, "HHOLDS": 806, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.02705631, 51.5296448, -0.02149043, 51.5346738 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02191146, 51.53215511 ], [ -0.02289464, 51.53157417 ], [ -0.02304911, 51.5315894 ], [ -0.02324253, 51.53125393 ], [ -0.02349718, 51.53117022 ], [ -0.02298442, 51.53027528 ], [ -0.02363133, 51.53012999 ], [ -0.02500745, 51.52987791 ], [ -0.02599936, 51.52973696 ], [ -0.02687986, 51.5296448 ], [ -0.02688343, 51.53000588 ], [ -0.02644447, 51.53017526 ], [ -0.02647645, 51.53025757 ], [ -0.02705631, 51.5307102 ], [ -0.02643106, 51.5307185 ], [ -0.02631149, 51.53063979 ], [ -0.02572332, 51.53064484 ], [ -0.02589903, 51.53040139 ], [ -0.02570323, 51.53024624 ], [ -0.02585168, 51.52990793 ], [ -0.02495545, 51.53003821 ], [ -0.02474868, 51.53015163 ], [ -0.02395979, 51.53039014 ], [ -0.02364556, 51.53065463 ], [ -0.02433552, 51.53115441 ], [ -0.02466697, 51.53103343 ], [ -0.02475055, 51.53129487 ], [ -0.02563568, 51.53142439 ], [ -0.02579945, 51.53156757 ], [ -0.02552664, 51.53199828 ], [ -0.02554082, 51.53217036 ], [ -0.02442441, 51.53264616 ], [ -0.02430253, 51.53279699 ], [ -0.0246725, 51.53359247 ], [ -0.02502026, 51.53387023 ], [ -0.02545345, 51.53440159 ], [ -0.02490631, 51.53442082 ], [ -0.02384577, 51.5346738 ], [ -0.02362227, 51.53452114 ], [ -0.02210117, 51.53368615 ], [ -0.02222189, 51.53356228 ], [ -0.02185246, 51.53335709 ], [ -0.02149043, 51.53336109 ], [ -0.02253148, 51.53278203 ], [ -0.02235684, 51.53263198 ], [ -0.02244837, 51.5324746 ], [ -0.02191146, 51.53215511 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 122, "LSOA11CD": "E01004325", "LSOA11NM": "Tower Hamlets 021D", "MSOA11CD": "E02000884", "MSOA11NM": "Tower Hamlets 021", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2487, "HHOLDRES": 2475, "COMESTRES": 12, "POPDEN": 182.200000, "HHOLDS": 1033, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.07128115, 51.51225033, -0.06537327, 51.51496526 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.06555445, 51.51477068 ], [ -0.06547066, 51.51390467 ], [ -0.06542091, 51.5135005 ], [ -0.06587219, 51.51347163 ], [ -0.06585118, 51.5131294 ], [ -0.06542713, 51.51325117 ], [ -0.06537327, 51.51292417 ], [ -0.06604293, 51.51288383 ], [ -0.06673535, 51.51277619 ], [ -0.06667517, 51.51250984 ], [ -0.06702129, 51.51246574 ], [ -0.06699856, 51.51232148 ], [ -0.06759247, 51.51225033 ], [ -0.06763569, 51.51248826 ], [ -0.06810993, 51.51251726 ], [ -0.06822791, 51.51260253 ], [ -0.06868788, 51.5126101 ], [ -0.07001574, 51.51311842 ], [ -0.07037227, 51.51397373 ], [ -0.07070699, 51.51392031 ], [ -0.07125841, 51.51451392 ], [ -0.07128115, 51.51465817 ], [ -0.07089149, 51.5148007 ], [ -0.069628, 51.51438103 ], [ -0.06917598, 51.51496526 ], [ -0.06796843, 51.51494537 ], [ -0.06766787, 51.51489545 ], [ -0.06636101, 51.51478398 ], [ -0.06555445, 51.51477068 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 123, "LSOA11CD": "E01004310", "LSOA11NM": "Tower Hamlets 015E", "MSOA11CD": "E02000878", "MSOA11NM": "Tower Hamlets 015", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1971, "HHOLDRES": 1893, "COMESTRES": 78, "POPDEN": 214.500000, "HHOLDS": 793, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.07394854, 51.51075112, -0.06629602, 51.51514967 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.07128115, 51.51465817 ], [ -0.07125841, 51.51451392 ], [ -0.07070699, 51.51392031 ], [ -0.07037227, 51.51397373 ], [ -0.07001574, 51.51311842 ], [ -0.06868788, 51.5126101 ], [ -0.06822791, 51.51260253 ], [ -0.06810993, 51.51251726 ], [ -0.06763569, 51.51248826 ], [ -0.06759247, 51.51225033 ], [ -0.06699856, 51.51232148 ], [ -0.06702129, 51.51246574 ], [ -0.06667517, 51.51250984 ], [ -0.06645616, 51.51253736 ], [ -0.06629602, 51.5115545 ], [ -0.06690883, 51.51171748 ], [ -0.06686061, 51.5111302 ], [ -0.06977509, 51.5109271 ], [ -0.07274413, 51.51075112 ], [ -0.07302419, 51.51162774 ], [ -0.07324742, 51.51289096 ], [ -0.07346701, 51.51362157 ], [ -0.07364334, 51.51407728 ], [ -0.07394854, 51.51439921 ], [ -0.07280489, 51.51481966 ], [ -0.07192566, 51.51514967 ], [ -0.07170298, 51.51490792 ], [ -0.07161811, 51.51452882 ], [ -0.07128115, 51.51465817 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 124, "LSOA11CD": "E01032769", "LSOA11NM": "Tower Hamlets 025F", "MSOA11CD": "E02000888", "MSOA11NM": "Tower Hamlets 025", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1235, "HHOLDRES": 1230, "COMESTRES": 5, "POPDEN": 119.800000, "HHOLDS": 593, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.03987539, 51.50851993, -0.03487179, 51.51263636 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03886167, 51.50851993 ], [ -0.03939961, 51.50854134 ], [ -0.03962586, 51.50855097 ], [ -0.03960478, 51.50983304 ], [ -0.03987539, 51.51025115 ], [ -0.0395244, 51.51076868 ], [ -0.03971408, 51.51083924 ], [ -0.03925311, 51.51102451 ], [ -0.03923292, 51.51115907 ], [ -0.03838381, 51.51152552 ], [ -0.03850159, 51.51170589 ], [ -0.03903029, 51.5119904 ], [ -0.03895784, 51.51253037 ], [ -0.03875363, 51.51263636 ], [ -0.0364436, 51.51251439 ], [ -0.03661262, 51.51214448 ], [ -0.03677069, 51.5116105 ], [ -0.03622299, 51.51159052 ], [ -0.03539569, 51.51145358 ], [ -0.03487179, 51.51127857 ], [ -0.03564815, 51.51079866 ], [ -0.03653939, 51.51013967 ], [ -0.03886167, 51.50851993 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 125, "LSOA11CD": "E01004289", "LSOA11NM": "Tower Hamlets 016C", "MSOA11CD": "E02000879", "MSOA11NM": "Tower Hamlets 016", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1844, "HHOLDRES": 1844, "COMESTRES": 0, "POPDEN": 175.800000, "HHOLDS": 670, "AVHHOLDSZ": 2.800000 }, "bbox": [ -0.04545332, 51.50808071, -0.03838381, 51.51311823 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.03939961, 51.50854134 ], [ -0.04056132, 51.50858178 ], [ -0.04208194, 51.50853384 ], [ -0.04332862, 51.5084258 ], [ -0.04390973, 51.50831676 ], [ -0.04464855, 51.5081273 ], [ -0.04482406, 51.50808071 ], [ -0.04545332, 51.51020897 ], [ -0.04544026, 51.51024651 ], [ -0.0420776, 51.51069401 ], [ -0.04213085, 51.51146828 ], [ -0.04289106, 51.51155291 ], [ -0.0430544, 51.51211319 ], [ -0.0430037, 51.51240328 ], [ -0.04368432, 51.5124168 ], [ -0.04368871, 51.51311823 ], [ -0.0433796, 51.51310024 ], [ -0.04187941, 51.51289942 ], [ -0.04121514, 51.51279028 ], [ -0.04016765, 51.51269631 ], [ -0.03875363, 51.51263636 ], [ -0.03895784, 51.51253037 ], [ -0.03903029, 51.5119904 ], [ -0.03850159, 51.51170589 ], [ -0.03838381, 51.51152552 ], [ -0.03923292, 51.51115907 ], [ -0.03925311, 51.51102451 ], [ -0.03971408, 51.51083924 ], [ -0.0395244, 51.51076868 ], [ -0.03987539, 51.51025115 ], [ -0.03960478, 51.50983304 ], [ -0.03962586, 51.50855097 ], [ -0.03939961, 51.50854134 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 126, "LSOA11CD": "E01004280", "LSOA11NM": "Tower Hamlets 032A", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 137.900000, "HHOLDS": 769, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.02473594, 51.49658271, -0.01879708, 51.49892965 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02131138, 51.49784713 ], [ -0.02158707, 51.49763557 ], [ -0.02158064, 51.49689651 ], [ -0.02235833, 51.49687225 ], [ -0.0223445, 51.4966174 ], [ -0.022786, 51.49658271 ], [ -0.02306327, 51.49660074 ], [ -0.02303093, 51.49685819 ], [ -0.02434259, 51.49683463 ], [ -0.02426136, 51.49716502 ], [ -0.02359434, 51.49714944 ], [ -0.02325297, 51.49732173 ], [ -0.02309265, 51.49731425 ], [ -0.02286105, 51.49751181 ], [ -0.02463539, 51.49746078 ], [ -0.02473594, 51.49772556 ], [ -0.02448757, 51.49802843 ], [ -0.02429991, 51.49811154 ], [ -0.02367203, 51.49798417 ], [ -0.02329533, 51.49777333 ], [ -0.02330822, 51.49850509 ], [ -0.02310111, 51.49864637 ], [ -0.02289952, 51.49841635 ], [ -0.02243972, 51.49859175 ], [ -0.0220039, 51.49867349 ], [ -0.01975967, 51.49892965 ], [ -0.01938547, 51.49890416 ], [ -0.01879708, 51.49886409 ], [ -0.01889246, 51.49832613 ], [ -0.01991272, 51.49838832 ], [ -0.01996758, 51.49845221 ], [ -0.02064231, 51.49850856 ], [ -0.02066867, 51.49832618 ], [ -0.02131138, 51.49784713 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 127, "LSOA11CD": "E01032780", "LSOA11NM": "Tower Hamlets 028I", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1333, "HHOLDRES": 1333, "COMESTRES": 0, "POPDEN": 37.800000, "HHOLDS": 647, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.02585154, 51.49847117, -0.01350183, 51.50564707 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01506307, 51.50439463 ], [ -0.01517337, 51.50400559 ], [ -0.01507915, 51.50393557 ], [ -0.01350183, 51.50375766 ], [ -0.01381114, 51.50269218 ], [ -0.01468432, 51.5027837 ], [ -0.01481345, 51.50275497 ], [ -0.01493072, 51.50235677 ], [ -0.01596527, 51.50117978 ], [ -0.0161664, 51.50011224 ], [ -0.01621238, 51.49988589 ], [ -0.0165291, 51.49991291 ], [ -0.01669618, 51.49847117 ], [ -0.01681886, 51.49850732 ], [ -0.01825449, 51.49916602 ], [ -0.01874326, 51.49920444 ], [ -0.01864291, 51.49978427 ], [ -0.01804706, 51.49976194 ], [ -0.01784359, 51.50028503 ], [ -0.01931958, 51.50043767 ], [ -0.02087689, 51.50074275 ], [ -0.02098148, 51.50010554 ], [ -0.02129982, 51.50016816 ], [ -0.02155649, 51.50012584 ], [ -0.02155578, 51.49939389 ], [ -0.02177635, 51.4993327 ], [ -0.02212187, 51.49965159 ], [ -0.02249458, 51.49984069 ], [ -0.02296429, 51.49989062 ], [ -0.02280741, 51.50012403 ], [ -0.02285154, 51.50029017 ], [ -0.02306423, 51.50047389 ], [ -0.02439361, 51.50047303 ], [ -0.02430168, 51.50079625 ], [ -0.02401328, 51.50061924 ], [ -0.02366353, 51.50079641 ], [ -0.02364708, 51.50110712 ], [ -0.02327952, 51.50129263 ], [ -0.02311832, 51.50122121 ], [ -0.02237546, 51.50107379 ], [ -0.02226689, 51.50125181 ], [ -0.02187671, 51.50129328 ], [ -0.02144891, 51.50261118 ], [ -0.02388477, 51.50285554 ], [ -0.02517583, 51.50300451 ], [ -0.02522996, 51.50337011 ], [ -0.02537669, 51.50364236 ], [ -0.02556116, 51.50370842 ], [ -0.0257974, 51.50391024 ], [ -0.02563981, 51.50422234 ], [ -0.02570989, 51.50460122 ], [ -0.02585154, 51.50476048 ], [ -0.0242641, 51.50506583 ], [ -0.02401626, 51.50503076 ], [ -0.02389111, 51.50543944 ], [ -0.02354225, 51.50541003 ], [ -0.02338968, 51.5056053 ], [ -0.02320054, 51.50564707 ], [ -0.02020348, 51.50530874 ], [ -0.01846777, 51.50512654 ], [ -0.01835687, 51.50502574 ], [ -0.01842616, 51.50475713 ], [ -0.01677609, 51.50459434 ], [ -0.01506307, 51.50439463 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 128, "LSOA11CD": "E01032770", "LSOA11NM": "Tower Hamlets 032B", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1191, "HHOLDRES": 1191, "COMESTRES": 0, "POPDEN": 271.900000, "HHOLDS": 572, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.02546127, 51.49777333, -0.01784359, 51.50074275 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01874326, 51.49920444 ], [ -0.01942212, 51.49925642 ], [ -0.01938547, 51.49890416 ], [ -0.01975967, 51.49892965 ], [ -0.0220039, 51.49867349 ], [ -0.02243972, 51.49859175 ], [ -0.02289952, 51.49841635 ], [ -0.02310111, 51.49864637 ], [ -0.02330822, 51.49850509 ], [ -0.02329533, 51.49777333 ], [ -0.02367203, 51.49798417 ], [ -0.02429991, 51.49811154 ], [ -0.02431501, 51.49825546 ], [ -0.0241359, 51.49843504 ], [ -0.02420727, 51.4987328 ], [ -0.02480958, 51.49873149 ], [ -0.02472671, 51.49922018 ], [ -0.02482346, 51.49951365 ], [ -0.0254369, 51.49969875 ], [ -0.02546127, 51.50001967 ], [ -0.02514293, 51.50002333 ], [ -0.02493672, 51.50011425 ], [ -0.02478661, 51.50036757 ], [ -0.02439361, 51.50047303 ], [ -0.02306423, 51.50047389 ], [ -0.02285154, 51.50029017 ], [ -0.02280741, 51.50012403 ], [ -0.02296429, 51.49989062 ], [ -0.02249458, 51.49984069 ], [ -0.02212187, 51.49965159 ], [ -0.02177635, 51.4993327 ], [ -0.02155578, 51.49939389 ], [ -0.02155649, 51.50012584 ], [ -0.02129982, 51.50016816 ], [ -0.02098148, 51.50010554 ], [ -0.02087689, 51.50074275 ], [ -0.01931958, 51.50043767 ], [ -0.01784359, 51.50028503 ], [ -0.01804706, 51.49976194 ], [ -0.01864291, 51.49978427 ], [ -0.01874326, 51.49920444 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 129, "LSOA11CD": "E01032770", "LSOA11NM": "Tower Hamlets 032B", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1191, "HHOLDRES": 1191, "COMESTRES": 0, "POPDEN": 271.900000, "HHOLDS": 572, "AVHHOLDSZ": 2.100000 }, "bbox": [ -0.02131138, 51.4969069, -0.01681886, 51.49925642 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01681886, 51.49850732 ], [ -0.01894405, 51.49792087 ], [ -0.0191143, 51.4969069 ], [ -0.01957053, 51.49710064 ], [ -0.02023446, 51.49715639 ], [ -0.02110822, 51.49715892 ], [ -0.02131138, 51.49784713 ], [ -0.02066867, 51.49832618 ], [ -0.02064231, 51.49850856 ], [ -0.01996758, 51.49845221 ], [ -0.01991272, 51.49838832 ], [ -0.01889246, 51.49832613 ], [ -0.01879708, 51.49886409 ], [ -0.01938547, 51.49890416 ], [ -0.01942212, 51.49925642 ], [ -0.01874326, 51.49920444 ], [ -0.01825449, 51.49916602 ], [ -0.01681886, 51.49850732 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 130, "LSOA11CD": "E01004280", "LSOA11NM": "Tower Hamlets 032A", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 137.900000, "HHOLDS": 769, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.02470545, 51.49281992, -0.01669618, 51.49850732 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.01728093, 51.49384959 ], [ -0.01748, 51.49377714 ], [ -0.01767621, 51.49281992 ], [ -0.01894068, 51.49289525 ], [ -0.01899203, 51.49304001 ], [ -0.01927448, 51.49317067 ], [ -0.02173226, 51.4933021 ], [ -0.02249025, 51.49335646 ], [ -0.0243828, 51.49350995 ], [ -0.02436834, 51.49366205 ], [ -0.02415705, 51.49370209 ], [ -0.02413885, 51.49439219 ], [ -0.02470545, 51.49448168 ], [ -0.02391231, 51.49485866 ], [ -0.0239851, 51.49550737 ], [ -0.02142523, 51.49554985 ], [ -0.0214104, 51.4963287 ], [ -0.02144871, 51.49636586 ], [ -0.02278242, 51.49633242 ], [ -0.022786, 51.49658271 ], [ -0.0223445, 51.4966174 ], [ -0.02235833, 51.49687225 ], [ -0.02158064, 51.49689651 ], [ -0.02158707, 51.49763557 ], [ -0.02131138, 51.49784713 ], [ -0.02110822, 51.49715892 ], [ -0.02023446, 51.49715639 ], [ -0.01957053, 51.49710064 ], [ -0.0191143, 51.4969069 ], [ -0.01894405, 51.49792087 ], [ -0.01681886, 51.49850732 ], [ -0.01669618, 51.49847117 ], [ -0.01695966, 51.49619727 ], [ -0.01728093, 51.49384959 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 131, "LSOA11CD": "E01004280", "LSOA11NM": "Tower Hamlets 032A", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 137.900000, "HHOLDS": 769, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.03019498, 51.48956294, -0.02428579, 51.49606847 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02630787, 51.49248858 ], [ -0.02641648, 51.49241672 ], [ -0.02542162, 51.49207164 ], [ -0.02516648, 51.49173268 ], [ -0.02516567, 51.49148419 ], [ -0.02428579, 51.49080443 ], [ -0.02556909, 51.49025825 ], [ -0.02700878, 51.48975001 ], [ -0.02747712, 51.48956294 ], [ -0.02777596, 51.48989573 ], [ -0.02841079, 51.49074864 ], [ -0.02918327, 51.49185552 ], [ -0.02975134, 51.49277545 ], [ -0.03007125, 51.49414731 ], [ -0.03015753, 51.49463129 ], [ -0.03019498, 51.49543327 ], [ -0.03017949, 51.49606847 ], [ -0.02654859, 51.49505756 ], [ -0.02659407, 51.49485592 ], [ -0.02684502, 51.49478186 ], [ -0.02689846, 51.49437822 ], [ -0.02715134, 51.49380126 ], [ -0.02630715, 51.49381581 ], [ -0.02630787, 51.49248858 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 132, "LSOA11CD": "E01032776", "LSOA11NM": "Tower Hamlets 028E", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1076, "HHOLDRES": 1076, "COMESTRES": 0, "POPDEN": 133.500000, "HHOLDS": 631, "AVHHOLDSZ": 1.700000 }, "bbox": [ -0.00717868, 51.50534047, 0.00107104, 51.50917131 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00029958, 51.50834217 ], [ -0.00097711, 51.50792628 ], [ -0.00084199, 51.50781299 ], [ 0.00023354, 51.50800981 ], [ 0.00107104, 51.5065117 ], [ 0.0004975, 51.50639864 ], [ -0.00047218, 51.50613851 ], [ -0.00089717, 51.50597657 ], [ -0.00158577, 51.50559459 ], [ -0.00195822, 51.50534047 ], [ -0.00338104, 51.50610264 ], [ -0.00389704, 51.50650316 ], [ -0.00435591, 51.50650621 ], [ -0.00485697, 51.50641694 ], [ -0.00471016, 51.50592237 ], [ -0.00546374, 51.5059075 ], [ -0.00558711, 51.50599053 ], [ -0.00622287, 51.50603409 ], [ -0.00641156, 51.50650566 ], [ -0.00682813, 51.50645212 ], [ -0.0070825, 51.50681395 ], [ -0.00717868, 51.50724639 ], [ -0.00658554, 51.50729926 ], [ -0.00637688, 51.50745758 ], [ -0.00518429, 51.50770708 ], [ -0.00528117, 51.50779866 ], [ -0.00543329, 51.50794513 ], [ -0.00525031, 51.50807461 ], [ -0.0045808, 51.50832632 ], [ -0.00401866, 51.50865848 ], [ -0.00346797, 51.50911425 ], [ -0.00337042, 51.50905827 ], [ -0.00283972, 51.50917131 ], [ -0.00238073, 51.50824553 ], [ -0.00125377, 51.50845496 ], [ -0.00108285, 51.50817456 ], [ -0.00079437, 51.50816964 ], [ -0.00029958, 51.50834217 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 133, "LSOA11CD": "E01032776", "LSOA11NM": "Tower Hamlets 028E", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1076, "HHOLDRES": 1076, "COMESTRES": 0, "POPDEN": 133.500000, "HHOLDS": 631, "AVHHOLDSZ": 1.700000 }, "bbox": [ -0.00767548, 51.50794513, 0.00045238, 51.51149018 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00029958, 51.50834217 ], [ -0.00079437, 51.50816964 ], [ -0.00108285, 51.50817456 ], [ -0.00125377, 51.50845496 ], [ -0.00238073, 51.50824553 ], [ -0.00283972, 51.50917131 ], [ -0.00337042, 51.50905827 ], [ -0.00346797, 51.50911425 ], [ -0.00401866, 51.50865848 ], [ -0.0045808, 51.50832632 ], [ -0.00525031, 51.50807461 ], [ -0.00543329, 51.50794513 ], [ -0.0064141, 51.50886042 ], [ -0.00686174, 51.50871902 ], [ -0.00689169, 51.50886922 ], [ -0.00762808, 51.50883678 ], [ -0.0076166, 51.5094301 ], [ -0.00767548, 51.50978198 ], [ -0.00687146, 51.50978282 ], [ -0.00693013, 51.51029974 ], [ -0.00690598, 51.51072518 ], [ -0.00543645, 51.51063713 ], [ -0.00550238, 51.5102805 ], [ -0.00412338, 51.51054876 ], [ -0.00444073, 51.51120165 ], [ -0.00290044, 51.51149018 ], [ -0.00239511, 51.51048113 ], [ -0.00147127, 51.5102421 ], [ -0.0014237, 51.509996 ], [ -0.00100086, 51.50973746 ], [ -0.00000687, 51.5093123 ], [ 0.00045238, 51.50848965 ], [ 0.00022999, 51.50836169 ], [ -0.00029958, 51.50834217 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 134, "LSOA11CD": "E01004243", "LSOA11NM": "Tower Hamlets 020A", "MSOA11CD": "E02000883", "MSOA11NM": "Tower Hamlets 020", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1789, "HHOLDRES": 1789, "COMESTRES": 0, "POPDEN": 153.400000, "HHOLDS": 614, "AVHHOLDSZ": 2.900000 }, "bbox": [ -0.0046523, 51.50545579, 0.00992548, 51.51458286 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.00107104, 51.5065117 ], [ 0.00023354, 51.50800981 ], [ -0.00084199, 51.50781299 ], [ -0.00097711, 51.50792628 ], [ -0.00029958, 51.50834217 ], [ 0.00022999, 51.50836169 ], [ 0.00045238, 51.50848965 ], [ -0.00000687, 51.5093123 ], [ -0.00100086, 51.50973746 ], [ -0.0014237, 51.509996 ], [ -0.00147127, 51.5102421 ], [ -0.00239511, 51.51048113 ], [ -0.00290044, 51.51149018 ], [ -0.00444073, 51.51120165 ], [ -0.0046523, 51.5116369 ], [ -0.00429845, 51.5120009 ], [ -0.00267487, 51.5122988 ], [ 0.0000259, 51.51282197 ], [ 0.00241746, 51.51411575 ], [ 0.00299081, 51.51433092 ], [ 0.00413422, 51.51458286 ], [ 0.00408078, 51.51433085 ], [ 0.00330749, 51.51304894 ], [ 0.00278272, 51.51225699 ], [ 0.00232433, 51.51137607 ], [ 0.00225386, 51.51114514 ], [ 0.00228048, 51.51082811 ], [ 0.00260999, 51.51055719 ], [ 0.00309156, 51.51048826 ], [ 0.00356195, 51.51049316 ], [ 0.00410274, 51.51066519 ], [ 0.00440225, 51.51104521 ], [ 0.00468915, 51.51193804 ], [ 0.00468824, 51.512635 ], [ 0.00477043, 51.51315294 ], [ 0.00490332, 51.51340991 ], [ 0.00535716, 51.5138369 ], [ 0.00589953, 51.51416683 ], [ 0.00617752, 51.51424089 ], [ 0.00663499, 51.51419696 ], [ 0.00694131, 51.51407481 ], [ 0.00743956, 51.51368788 ], [ 0.00764111, 51.51343698 ], [ 0.00779654, 51.51279301 ], [ 0.00777315, 51.51244508 ], [ 0.00764199, 51.51198209 ], [ 0.00724501, 51.51137316 ], [ 0.00650639, 51.5106762 ], [ 0.00615124, 51.51030121 ], [ 0.00601204, 51.50992126 ], [ 0.00626029, 51.50966731 ], [ 0.00690714, 51.50950632 ], [ 0.00853303, 51.50924242 ], [ 0.0090756, 51.50908642 ], [ 0.00937511, 51.50893347 ], [ 0.00977619, 51.50861241 ], [ 0.00992548, 51.50836156 ], [ 0.00988902, 51.50802452 ], [ 0.00936523, 51.50703066 ], [ 0.00878548, 51.50646364 ], [ 0.00762083, 51.50545579 ], [ 0.00598595, 51.50610857 ], [ 0.00519696, 51.50637458 ], [ 0.00416643, 51.50665762 ], [ 0.00380903, 51.50670252 ], [ 0.00223459, 51.50667953 ], [ 0.00107104, 51.5065117 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 135, "LSOA11CD": "E01032776", "LSOA11NM": "Tower Hamlets 028E", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1076, "HHOLDRES": 1076, "COMESTRES": 0, "POPDEN": 133.500000, "HHOLDS": 631, "AVHHOLDSZ": 1.700000 }, "bbox": [ -0.00750453, 51.50350024, -0.00195822, 51.50650621 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00195822, 51.50534047 ], [ -0.00240581, 51.50504862 ], [ -0.00289449, 51.50466561 ], [ -0.00321982, 51.50435176 ], [ -0.00396095, 51.50350024 ], [ -0.00551775, 51.5036623 ], [ -0.00582312, 51.50376808 ], [ -0.0068175, 51.50430716 ], [ -0.00716864, 51.50464108 ], [ -0.0071733, 51.50498227 ], [ -0.00727414, 51.50505892 ], [ -0.0074308, 51.50510138 ], [ -0.0074349, 51.505668 ], [ -0.00750453, 51.50593767 ], [ -0.00716888, 51.5059124 ], [ -0.00709166, 51.50560821 ], [ -0.00683743, 51.50539618 ], [ -0.00640476, 51.5056074 ], [ -0.00644232, 51.50600218 ], [ -0.00622287, 51.50603409 ], [ -0.00558711, 51.50599053 ], [ -0.00546374, 51.5059075 ], [ -0.00471016, 51.50592237 ], [ -0.00485697, 51.50641694 ], [ -0.00435591, 51.50650621 ], [ -0.00389704, 51.50650316 ], [ -0.00338104, 51.50610264 ], [ -0.00195822, 51.50534047 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 136, "LSOA11CD": "E01032776", "LSOA11NM": "Tower Hamlets 028E", "MSOA11CD": "E02000891", "MSOA11NM": "Tower Hamlets 028", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1076, "HHOLDRES": 1076, "COMESTRES": 0, "POPDEN": 133.500000, "HHOLDS": 631, "AVHHOLDSZ": 1.700000 }, "bbox": [ -0.0161664, 51.49956335, -0.00518429, 51.50782126 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.00528117, 51.50779866 ], [ -0.00518429, 51.50770708 ], [ -0.00637688, 51.50745758 ], [ -0.00658554, 51.50729926 ], [ -0.00717868, 51.50724639 ], [ -0.0070825, 51.50681395 ], [ -0.00682813, 51.50645212 ], [ -0.00641156, 51.50650566 ], [ -0.00622287, 51.50603409 ], [ -0.00644232, 51.50600218 ], [ -0.00640476, 51.5056074 ], [ -0.00683743, 51.50539618 ], [ -0.00709166, 51.50560821 ], [ -0.00716888, 51.5059124 ], [ -0.00750453, 51.50593767 ], [ -0.0074349, 51.505668 ], [ -0.0074308, 51.50510138 ], [ -0.00727414, 51.50505892 ], [ -0.00732894, 51.50479389 ], [ -0.00749871, 51.50453598 ], [ -0.00762907, 51.50452021 ], [ -0.00782959, 51.50421786 ], [ -0.00776009, 51.50397127 ], [ -0.00842584, 51.50277115 ], [ -0.00872028, 51.50196679 ], [ -0.0087192, 51.50166101 ], [ -0.00914341, 51.50151534 ], [ -0.00971183, 51.50158395 ], [ -0.00975359, 51.50128147 ], [ -0.01027622, 51.50131203 ], [ -0.01040341, 51.50100017 ], [ -0.01020802, 51.50097996 ], [ -0.0103747, 51.50051861 ], [ -0.01031857, 51.50038808 ], [ -0.010581, 51.49960627 ], [ -0.01123124, 51.49956335 ], [ -0.01339919, 51.4997711 ], [ -0.01458662, 51.49993496 ], [ -0.0161664, 51.50011224 ], [ -0.01596527, 51.50117978 ], [ -0.01493072, 51.50235677 ], [ -0.01481345, 51.50275497 ], [ -0.01468432, 51.5027837 ], [ -0.01381114, 51.50269218 ], [ -0.01350183, 51.50375766 ], [ -0.01507915, 51.50393557 ], [ -0.01517337, 51.50400559 ], [ -0.01506307, 51.50439463 ], [ -0.01488528, 51.50483199 ], [ -0.01330024, 51.50466562 ], [ -0.01319756, 51.50474819 ], [ -0.01258175, 51.5045156 ], [ -0.01239564, 51.50463244 ], [ -0.01309848, 51.50491442 ], [ -0.01313979, 51.50499957 ], [ -0.01289656, 51.50587042 ], [ -0.01330349, 51.50591539 ], [ -0.01324025, 51.50614743 ], [ -0.01278933, 51.50609932 ], [ -0.01265269, 51.50659036 ], [ -0.01231941, 51.50654944 ], [ -0.01212675, 51.50725435 ], [ -0.01093451, 51.50736467 ], [ -0.01067873, 51.50715693 ], [ -0.00928148, 51.50727311 ], [ -0.00878101, 51.50718369 ], [ -0.00845608, 51.50703428 ], [ -0.00795012, 51.50707065 ], [ -0.0074752, 51.50738632 ], [ -0.00758912, 51.50774796 ], [ -0.00705553, 51.50775689 ], [ -0.00647362, 51.50782126 ], [ -0.00582766, 51.50765735 ], [ -0.00528117, 51.50779866 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 137, "LSOA11CD": "E01004280", "LSOA11NM": "Tower Hamlets 032A", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 137.900000, "HHOLDS": 769, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.03002754, 51.4977866, -0.0241359, 51.50164948 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.0254369, 51.49969875 ], [ -0.02482346, 51.49951365 ], [ -0.02472671, 51.49922018 ], [ -0.02480958, 51.49873149 ], [ -0.02420727, 51.4987328 ], [ -0.0241359, 51.49843504 ], [ -0.02431501, 51.49825546 ], [ -0.02429991, 51.49811154 ], [ -0.02448757, 51.49802843 ], [ -0.02477637, 51.49804017 ], [ -0.02488873, 51.49793268 ], [ -0.0258689, 51.49792221 ], [ -0.02588954, 51.49811141 ], [ -0.02632809, 51.49815236 ], [ -0.02617807, 51.49834179 ], [ -0.02647381, 51.4985278 ], [ -0.02691718, 51.4985776 ], [ -0.02694192, 51.49841986 ], [ -0.02723932, 51.49820783 ], [ -0.02682548, 51.49817394 ], [ -0.02667716, 51.4980887 ], [ -0.02664477, 51.49780627 ], [ -0.03002754, 51.4977866 ], [ -0.02996203, 51.49880982 ], [ -0.02954334, 51.50106364 ], [ -0.0294715, 51.50160047 ], [ -0.02715062, 51.50164948 ], [ -0.02682532, 51.50156866 ], [ -0.02595832, 51.50152085 ], [ -0.02537897, 51.50149398 ], [ -0.02509607, 51.50123865 ], [ -0.02531402, 51.50100935 ], [ -0.02523384, 51.50084318 ], [ -0.02541772, 51.50052703 ], [ -0.02559767, 51.50045867 ], [ -0.02604773, 51.50045221 ], [ -0.02601379, 51.49978217 ], [ -0.0264924, 51.49976587 ], [ -0.02675086, 51.49941399 ], [ -0.02665529, 51.49916649 ], [ -0.02597368, 51.49916499 ], [ -0.0258985, 51.49823746 ], [ -0.02540744, 51.49826517 ], [ -0.02533273, 51.49832685 ], [ -0.0254369, 51.49969875 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 138, "LSOA11CD": "E01004277", "LSOA11NM": "Tower Hamlets 033A", "MSOA11CD": "E02006854", "MSOA11NM": "Tower Hamlets 033", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1630, "HHOLDRES": 1630, "COMESTRES": 0, "POPDEN": 37.800000, "HHOLDS": 898, "AVHHOLDSZ": 1.800000 }, "bbox": [ -0.02675086, 51.49823746, -0.02144891, 51.50370842 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02439361, 51.50047303 ], [ -0.02478661, 51.50036757 ], [ -0.02493672, 51.50011425 ], [ -0.02514293, 51.50002333 ], [ -0.02546127, 51.50001967 ], [ -0.0254369, 51.49969875 ], [ -0.02533273, 51.49832685 ], [ -0.02540744, 51.49826517 ], [ -0.0258985, 51.49823746 ], [ -0.02597368, 51.49916499 ], [ -0.02665529, 51.49916649 ], [ -0.02675086, 51.49941399 ], [ -0.0264924, 51.49976587 ], [ -0.02601379, 51.49978217 ], [ -0.02604773, 51.50045221 ], [ -0.02559767, 51.50045867 ], [ -0.02541772, 51.50052703 ], [ -0.02523384, 51.50084318 ], [ -0.02531402, 51.50100935 ], [ -0.02509607, 51.50123865 ], [ -0.02537897, 51.50149398 ], [ -0.02595832, 51.50152085 ], [ -0.02589417, 51.50233812 ], [ -0.02568449, 51.50318891 ], [ -0.02570046, 51.50348594 ], [ -0.02556116, 51.50370842 ], [ -0.02537669, 51.50364236 ], [ -0.02522996, 51.50337011 ], [ -0.02517583, 51.50300451 ], [ -0.02388477, 51.50285554 ], [ -0.02144891, 51.50261118 ], [ -0.02187671, 51.50129328 ], [ -0.02226689, 51.50125181 ], [ -0.02237546, 51.50107379 ], [ -0.02311832, 51.50122121 ], [ -0.02327952, 51.50129263 ], [ -0.02364708, 51.50110712 ], [ -0.02366353, 51.50079641 ], [ -0.02401328, 51.50061924 ], [ -0.02430168, 51.50079625 ], [ -0.02439361, 51.50047303 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 139, "LSOA11CD": "E01004280", "LSOA11NM": "Tower Hamlets 032A", "MSOA11CD": "E02006853", "MSOA11NM": "Tower Hamlets 032", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1879, "HHOLDRES": 1879, "COMESTRES": 0, "POPDEN": 137.900000, "HHOLDS": 769, "AVHHOLDSZ": 2.400000 }, "bbox": [ -0.02747712, 51.48643784, -0.02157809, 51.49394042 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02244137, 51.49194564 ], [ -0.02282707, 51.49197164 ], [ -0.02285657, 51.49176938 ], [ -0.02309121, 51.49179 ], [ -0.02334638, 51.49167677 ], [ -0.02291346, 51.49150175 ], [ -0.02374515, 51.49113945 ], [ -0.02331104, 51.49077476 ], [ -0.02228254, 51.48997862 ], [ -0.02313611, 51.48954524 ], [ -0.02362992, 51.49001269 ], [ -0.0239105, 51.48968471 ], [ -0.02361931, 51.48943608 ], [ -0.02352735, 51.48917859 ], [ -0.02284847, 51.48903892 ], [ -0.02289386, 51.48881496 ], [ -0.02272834, 51.48855677 ], [ -0.02295383, 51.48837663 ], [ -0.02157809, 51.48761793 ], [ -0.02303404, 51.4865397 ], [ -0.02280426, 51.48643784 ], [ -0.02299724, 51.48652006 ], [ -0.02380251, 51.48692608 ], [ -0.02504158, 51.48766906 ], [ -0.02618361, 51.48847095 ], [ -0.0270909, 51.48918486 ], [ -0.02747712, 51.48956294 ], [ -0.02700878, 51.48975001 ], [ -0.02556909, 51.49025825 ], [ -0.02428579, 51.49080443 ], [ -0.02516567, 51.49148419 ], [ -0.02516648, 51.49173268 ], [ -0.02542162, 51.49207164 ], [ -0.02641648, 51.49241672 ], [ -0.02630787, 51.49248858 ], [ -0.02580183, 51.49267116 ], [ -0.02547928, 51.49297842 ], [ -0.02503682, 51.4932091 ], [ -0.02488032, 51.49318266 ], [ -0.02489571, 51.49386078 ], [ -0.02462808, 51.49394042 ], [ -0.02458924, 51.49353013 ], [ -0.0243828, 51.49350995 ], [ -0.02249025, 51.49335646 ], [ -0.02251205, 51.49328146 ], [ -0.02216597, 51.49292778 ], [ -0.02190032, 51.49280412 ], [ -0.02192921, 51.4925498 ], [ -0.02234771, 51.4925705 ], [ -0.02232349, 51.4924457 ], [ -0.0225226, 51.49224475 ], [ -0.0224032, 51.4921495 ], [ -0.02244137, 51.49194564 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 140, "LSOA11CD": "E01004224", "LSOA11NM": "Tower Hamlets 001C", "MSOA11CD": "E02000864", "MSOA11NM": "Tower Hamlets 001", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2000, "HHOLDRES": 2000, "COMESTRES": 0, "POPDEN": 45.600000, "HHOLDS": 806, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.03001459, 51.52934895, -0.02364556, 51.53217036 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.02705631, 51.5307102 ], [ -0.02647645, 51.53025757 ], [ -0.02644447, 51.53017526 ], [ -0.02688343, 51.53000588 ], [ -0.02687986, 51.5296448 ], [ -0.02722757, 51.52961349 ], [ -0.0286078, 51.52949292 ], [ -0.02988188, 51.52934895 ], [ -0.03001459, 51.52951931 ], [ -0.02909708, 51.53009122 ], [ -0.02944629, 51.53025801 ], [ -0.0288272, 51.530526 ], [ -0.02903246, 51.53079496 ], [ -0.02854644, 51.5310385 ], [ -0.0287176, 51.53136578 ], [ -0.02862009, 51.53149462 ], [ -0.02901001, 51.53196792 ], [ -0.02842069, 51.53215067 ], [ -0.02804847, 51.53187325 ], [ -0.0275825, 51.53174837 ], [ -0.02703062, 51.53139507 ], [ -0.02676046, 51.5315338 ], [ -0.02641769, 51.53127365 ], [ -0.02594593, 51.53152007 ], [ -0.02636059, 51.531756 ], [ -0.02577602, 51.53206641 ], [ -0.02554082, 51.53217036 ], [ -0.02552664, 51.53199828 ], [ -0.02579945, 51.53156757 ], [ -0.02563568, 51.53142439 ], [ -0.02475055, 51.53129487 ], [ -0.02466697, 51.53103343 ], [ -0.02433552, 51.53115441 ], [ -0.02364556, 51.53065463 ], [ -0.02395979, 51.53039014 ], [ -0.02474868, 51.53015163 ], [ -0.02495545, 51.53003821 ], [ -0.02585168, 51.52990793 ], [ -0.02570323, 51.53024624 ], [ -0.02589903, 51.53040139 ], [ -0.02572332, 51.53064484 ], [ -0.02631149, 51.53063979 ], [ -0.02643106, 51.5307185 ], [ -0.02705631, 51.5307102 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 141, "LSOA11CD": "E01004234", "LSOA11NM": "Tower Hamlets 003E", "MSOA11CD": "E02000866", "MSOA11NM": "Tower Hamlets 003", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 2218, "HHOLDRES": 2218, "COMESTRES": 0, "POPDEN": 38.700000, "HHOLDS": 903, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.04533655, 51.52684018, -0.03994505, 51.53048189 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04220901, 51.53033262 ], [ -0.04137642, 51.5291788 ], [ -0.04061639, 51.52824393 ], [ -0.03994505, 51.52725139 ], [ -0.04214217, 51.52699904 ], [ -0.04312644, 51.52690755 ], [ -0.04352484, 51.52684018 ], [ -0.04366484, 51.52722246 ], [ -0.04304367, 51.52752601 ], [ -0.04335376, 51.52784374 ], [ -0.04324563, 51.5278695 ], [ -0.04341899, 51.52841954 ], [ -0.04376308, 51.52875962 ], [ -0.04486179, 51.52956846 ], [ -0.04527629, 51.52938281 ], [ -0.04533655, 51.52949836 ], [ -0.04409538, 51.52986435 ], [ -0.044245, 51.53007368 ], [ -0.04402504, 51.53015994 ], [ -0.04385543, 51.53043964 ], [ -0.04337896, 51.53038993 ], [ -0.04290407, 51.53048189 ], [ -0.04272135, 51.53021819 ], [ -0.04220901, 51.53033262 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 142, "LSOA11CD": "E01004201", "LSOA11NM": "Tower Hamlets 002D", "MSOA11CD": "E02000865", "MSOA11NM": "Tower Hamlets 002", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1556, "HHOLDRES": 1533, "COMESTRES": 23, "POPDEN": 119.900000, "HHOLDS": 619, "AVHHOLDSZ": 2.500000 }, "bbox": [ -0.04783902, 51.52845682, -0.04220901, 51.53179564 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04220901, 51.53033262 ], [ -0.04272135, 51.53021819 ], [ -0.04290407, 51.53048189 ], [ -0.04337896, 51.53038993 ], [ -0.04385543, 51.53043964 ], [ -0.04402504, 51.53015994 ], [ -0.044245, 51.53007368 ], [ -0.04409538, 51.52986435 ], [ -0.04533655, 51.52949836 ], [ -0.04527629, 51.52938281 ], [ -0.04528505, 51.52916729 ], [ -0.04619441, 51.52897328 ], [ -0.04630344, 51.52911519 ], [ -0.0466782, 51.52914301 ], [ -0.04640322, 51.5285836 ], [ -0.0467489, 51.52845682 ], [ -0.04698366, 51.52849587 ], [ -0.0472181, 51.52885652 ], [ -0.04737783, 51.52896581 ], [ -0.04768707, 51.52946427 ], [ -0.04769153, 51.52969935 ], [ -0.04783168, 51.52985193 ], [ -0.04783902, 51.53006184 ], [ -0.04754601, 51.53012916 ], [ -0.04714517, 51.52992329 ], [ -0.04692614, 51.53032502 ], [ -0.04629477, 51.53044816 ], [ -0.04638177, 51.53051654 ], [ -0.04614148, 51.53085646 ], [ -0.0456534, 51.53094894 ], [ -0.04542071, 51.53120809 ], [ -0.04536604, 51.53138733 ], [ -0.04475126, 51.53161258 ], [ -0.04448662, 51.53179564 ], [ -0.04334451, 51.53125667 ], [ -0.04294193, 51.53104158 ], [ -0.04247852, 51.53064757 ], [ -0.04220901, 51.53033262 ] ] ] } },
{ "type": "Feature", "properties": { "FID": 143, "LSOA11CD": "E01004208", "LSOA11NM": "Tower Hamlets 013C", "MSOA11CD": "E02000876", "MSOA11NM": "Tower Hamlets 013", "LAD11CD": "E09000030", "LAD11NM": "Tower Hamlets", "RGN11CD": "E12000007", "RGN11NM": "London", "USUALRES": 1976, "HHOLDRES": 1842, "COMESTRES": 134, "POPDEN": 122.100000, "HHOLDS": 788, "AVHHOLDSZ": 2.300000 }, "bbox": [ -0.05451012, 51.52274348, -0.04892247, 51.52784521 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.04914712, 51.52503776 ], [ -0.04892247, 51.52483127 ], [ -0.04944133, 51.52446351 ], [ -0.04929657, 51.52424339 ], [ -0.0490303, 51.52407602 ], [ -0.04982272, 51.52380938 ], [ -0.04986935, 51.52384927 ], [ -0.0507682, 51.52356405 ], [ -0.05114187, 51.52326587 ], [ -0.05152956, 51.52319237 ], [ -0.05156088, 51.52304387 ], [ -0.05218194, 51.5228137 ], [ -0.05292285, 51.52276734 ], [ -0.05297584, 51.52282105 ], [ -0.05431716, 51.52274348 ], [ -0.05450119, 51.52280743 ], [ -0.05451012, 51.52366431 ], [ -0.05399817, 51.52343263 ], [ -0.05398705, 51.52307748 ], [ -0.05307095, 51.52310622 ], [ -0.05321388, 51.52430565 ], [ -0.05292199, 51.52506519 ], [ -0.05249314, 51.52599332 ], [ -0.05193733, 51.5262795 ], [ -0.05201362, 51.52644952 ], [ -0.05179559, 51.52662994 ], [ -0.05178445, 51.52695412 ], [ -0.05267081, 51.52682937 ], [ -0.05261605, 51.52663696 ], [ -0.05299289, 51.52667562 ], [ -0.0531744, 51.52727249 ], [ -0.0533304, 51.52752421 ], [ -0.05113639, 51.52784521 ], [ -0.0504415, 51.52649895 ], [ -0.04991255, 51.52574094 ], [ -0.04914712, 51.52503776 ] ] ] } }
]
}

Wyświetl plik

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ViziCities - Basic Example</title>
<style type="text/css">
html, body {
height: 100%;
width: 100%;
}
body {
background: #222;
margin: 0;
overflow: hidden;
padding: 0;
}
#vizicities-viewport {
height: 720px;
left: 50%;
margin: -360px 0 0 -640px;
position: absolute;
top: 50%;
width: 1280px;
}
</style>
<link rel="stylesheet" type="text/css" href="../../build/vizi.css">
</head>
<body>
<div id="vizicities-viewport"></div>
<script src="../../build/vizi.js"></script>
<script src="main.js"></script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,224 @@
var world = new VIZI.World({
viewport: document.querySelector("#vizicities-viewport"),
layersUI: true,
picking: true
// center: new VIZI.LatLon(40.01000594412381, -105.2727379358738) // Collada
});
var controls = new VIZI.ControlsMap(world.camera, {
viewport: world.options.viewport
});
var pickControls = new VIZI.ControlsMousePick(world.camera, {
scene: world.scene
});
var descriptionUI = new VIZI.DescriptionUI({
title: "Basic example",
body: "This is a basic example showing a 2D basemap, 3D building tiles and a choropleth of population density."
});
var mapConfig = {
input: {
type: "BlueprintInputMapTiles",
options: {
tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
}
},
output: {
type: "BlueprintOutputImageTiles",
options: {
grids: [{
zoom: 19,
tilesPerDirection: 3,
cullZoom: 17
}, {
zoom: 18,
tilesPerDirection: 3,
cullZoom: 16
}, {
zoom: 17,
tilesPerDirection: 3,
cullZoom: 15
}, {
zoom: 16,
tilesPerDirection: 3,
cullZoom: 14
}, {
zoom: 15,
tilesPerDirection: 3,
cullZoom: 13
}, {
zoom: 14,
tilesPerDirection: 3,
cullZoom: 12
}, {
zoom: 13,
tilesPerDirection: 5,
cullZoom: 11
}]
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "output",
triggerName: "gridUpdated",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "input",
triggerName: "tileReceived",
triggerArguments: ["image", "tile"],
actionObject: "output",
actionName: "outputImageTile",
actionArguments: ["image", "tile"],
actionOutput: {
image: "image", // actionArg: triggerArg
tile: "tile"
}
}]
};
var switchboardMap = new VIZI.BlueprintSwitchboard(mapConfig);
switchboardMap.addToWorld(world);
var buildingsConfig = {
input: {
type: "BlueprintInputGeoJSON",
options: {
tilePath: "http://vector.mapzen.com/osm/buildings/{z}/{x}/{y}.json"
}
},
output: {
type: "BlueprintOutputBuildingTiles",
options: {
grids: [{
zoom: 15,
tilesPerDirection: 1,
cullZoom: 13
}],
workerURL: "../../build/vizi-worker.min.js"
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "output",
triggerName: "gridUpdated",
triggerArguments: ["tiles", "newTiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "newTiles" // actionArg: triggerArg
}
}, {
triggerObject: "input",
triggerName: "tileReceived",
triggerArguments: ["geoJSON", "tile"],
actionObject: "output",
actionName: "outputBuildingTile",
actionArguments: ["buildings", "tile"],
actionOutput: {
buildings: {
process: "map",
itemsObject: "geoJSON",
itemsProperties: "features",
transformation: {
outline: "geometry.coordinates",
height: "properties.height",
minHeight: "properties.min_height"
}
},
tile: "tile"
}
}]
};
var switchboardBuildings = new VIZI.BlueprintSwitchboard(buildingsConfig);
switchboardBuildings.addToWorld(world);
var choroplethConfig = {
input: {
type: "BlueprintInputGeoJSON",
options: {
path: "./data/sample.geojson"
}
},
output: {
type: "BlueprintOutputChoropleth",
options: {
colourRange: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],
layer: 100,
infoUI: true,
description: "Number of people per hectare"
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: [],
actionObject: "input",
actionName: "requestData",
actionArguments: [],
actionOutput: {}
}, {
triggerObject: "input",
triggerName: "dataReceived",
triggerArguments: ["geoJSON"],
actionObject: "output",
actionName: "outputChoropleth",
actionArguments: ["data"],
actionOutput: {
data: {
// Loop through each item in trigger.geoJSON and return a new array of processed values (a map)
process: "map",
itemsObject: "geoJSON",
itemsProperties: "features",
// Return a new object for each item with the given properties
transformation: {
outline: "geometry.coordinates[0]",
value: "properties.POPDEN"
}
}
}
}]
};
var switchboardChoropleth = new VIZI.BlueprintSwitchboard(choroplethConfig);
switchboardChoropleth.addToWorld(world);
var clock = new VIZI.Clock();
var update = function() {
var delta = clock.getDelta();
world.onTick(delta);
world.render();
window.requestAnimationFrame(update);
};
update();

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ViziCities - GPX Example</title>
<style type="text/css">
html, body {
height: 100%;
width: 100%;
}
body {
background: #222;
margin: 0;
overflow: hidden;
padding: 0;
}
#vizicities-viewport {
height: 720px;
left: 50%;
margin: -360px 0 0 -640px;
position: absolute;
top: 50%;
width: 1280px;
}
</style>
<link rel="stylesheet" type="text/css" href="../../build/vizi.css">
</head>
<body>
<div id="vizicities-viewport"></div>
<script src="../../build/vizi.js"></script>
<script src="main.js"></script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,141 @@
var world = new VIZI.World({
viewport: document.querySelector("#vizicities-viewport")
});
var controls = new VIZI.ControlsMap(world.camera, {
viewport: world.options.viewport
});
var gpxConfig = {
input: {
type: "BlueprintInputGPX",
options: {
path: "./data/sample.gpx"
}
},
output: {
type: "BlueprintOutputDebugLines",
options: {}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: [],
actionObject: "input",
actionName: "requestData",
actionArguments: [],
actionOutput: {}
}, {
triggerObject: "input",
triggerName: "dataReceived",
triggerArguments: ["gpx"],
actionObject: "output",
actionName: "outputLines",
actionArguments: ["data"],
actionOutput: {
data: {
process: "map",
itemsObject: "gpx",
itemsProperties: "trk.trkseg.trkpt",
transformation: {
coordinates: ["@lon", "@lat"],
height: "ele"
}
}
}
}]
};
var switchboardGPX = new VIZI.BlueprintSwitchboard(gpxConfig);
switchboardGPX.addToWorld(world);
var mapConfig = {
input: {
type: "BlueprintInputMapTiles",
options: {
tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
}
},
output: {
type: "BlueprintOutputImageTiles",
options: {
grids: [{
zoom: 19,
tilesPerDirection: 3,
cullZoom: 17
}, {
zoom: 18,
tilesPerDirection: 3,
cullZoom: 16
}, {
zoom: 17,
tilesPerDirection: 3,
cullZoom: 15
}, {
zoom: 16,
tilesPerDirection: 3,
cullZoom: 14
}, {
zoom: 15,
tilesPerDirection: 3,
cullZoom: 13
}, {
zoom: 14,
tilesPerDirection: 3,
cullZoom: 12
}, {
zoom: 13,
tilesPerDirection: 5,
cullZoom: 11
}]
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "output",
triggerName: "gridUpdated",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "input",
triggerName: "tileReceived",
triggerArguments: ["image", "tile"],
actionObject: "output",
actionName: "outputImageTile",
actionArguments: ["image", "tile"],
actionOutput: {
image: "image", // actionArg: triggerArg
tile: "tile"
}
}]
};
var switchboardMap = new VIZI.BlueprintSwitchboard(mapConfig);
switchboardMap.addToWorld(world);
var clock = new VIZI.Clock();
var update = function() {
var delta = clock.getDelta();
world.onTick(delta);
world.render();
window.requestAnimationFrame(update);
};
update();

Wyświetl plik

@ -1,45 +0,0 @@
<!DOCTYPE html5>
<html>
<head>
<meta charset="utf-8">
<title>ViziCities Demo</title>
<link href="reset.css" rel="stylesheet" type="text/css">
<link href="../css/vizicities.css" rel="stylesheet" type="text/css">
<link href="../css/loading.css" rel="stylesheet" type="text/css">
<style type="text/css">
html, body {
height: 100%;
overflow: hidden;
}
body {
background: #ccc;
}
</style>
</head>
<body>
<div id="vizicities-container"></div>
<script src="../build/vizi.js"></script>
<script>
// Debug output
VIZI.DEBUG = false;
VIZI.ENABLE_OUTLINES = false;
VIZI.ENABLE_ROADS = true;
var city = new VIZI.City();
city.init({
coords: [-0.01924, 51.50358], // Canary Wharf
domElement: document.getElementById("vizicities-container"),
overpassGridUpdate: true
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 5.3 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 7.6 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 7.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.5 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 16 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 24 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 6.8 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 9.3 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 8.8 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 5.4 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.0 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 11 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 3.9 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.5 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.6 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 4.9 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 4.4 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 45 KiB

Wyświetl plik

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Placemark>
<name>SketchUp Model of Macky Auditorium</name>
<description>University of Colorado, Boulder; model created by Noël Nemcik.</description>
<LookAt>
<longitude>-105.2727379358738</longitude>
<latitude>40.01000594412381</latitude>
<altitude>0</altitude>
<range>127.2393107680517</range>
<tilt>65.74454495876547</tilt>
<heading>-27.70337734057933</heading>
</LookAt>
<Model id="model_4">
<altitudeMode>relativeToGround</altitudeMode>
<Location>
<longitude>-105.272774533734</longitude>
<latitude>40.009993372683</latitude>
<altitude>0</altitude>
</Location>
<Orientation>
<heading>0</heading>
<tilt>0</tilt>
<roll>0</roll>
</Orientation>
<Scale>
<x>1</x>
<y>1</y>
<z>1</z>
</Scale>
<Link>
<href>files/CU Macky.dae</href>
</Link>
</Model>
</Placemark>
</kml>

Wyświetl plik

@ -0,0 +1,20 @@
<../files/CU-Macky---Center-StairsnoCulling.jpg> <CU-Macky---Center-StairsnoCulling.jpg> <model_4>
<../files/CU-Macky-4sideturretnoCulling.jpg> <CU-Macky-4sideturretnoCulling.jpg> <model_4>
<../files/CU-Macky-Back-NorthnoCulling.jpg> <CU-Macky-Back-NorthnoCulling.jpg> <model_4>
<../files/CU-Macky-BrickwallnoCulling.jpg> <CU-Macky-BrickwallnoCulling.jpg> <model_4>
<../files/CU-Macky-East-WingnoCulling.jpg> <CU-Macky-East-WingnoCulling.jpg> <model_4>
<../files/CU-Macky-EastdetaildoornoCulling.jpg> <CU-Macky-EastdetaildoornoCulling.jpg> <model_4>
<../files/CU-Macky-EastnoCulling.jpg> <CU-Macky-EastnoCulling.jpg> <model_4>
<../files/CU-Macky-EntrancenoCulling.jpg> <CU-Macky-EntrancenoCulling.jpg> <model_4>
<../files/CU-Macky-Front--TurretnoCulling.jpg> <CU-Macky-Front--TurretnoCulling.jpg> <model_4>
<../files/CU-Macky-FrontbrickwallnoCulling.jpg> <CU-Macky-FrontbrickwallnoCulling.jpg> <model_4>
<../files/CU-Macky-FrontnoCulling.jpg> <CU-Macky-FrontnoCulling.jpg> <model_4>
<../files/CU-Macky-FrontofTowernoCulling.jpg> <CU-Macky-FrontofTowernoCulling.jpg> <model_4>
<../files/CU-Macky-NortheastUnivnoCulling.jpg> <CU-Macky-NortheastUnivnoCulling.jpg> <model_4>
<../files/CU-Macky-NorthnoCulling.jpg> <CU-Macky-NorthnoCulling.jpg> <model_4>
<../files/CU-Macky-RoofnoCulling.jpg> <CU-Macky-RoofnoCulling.jpg> <model_4>
<../files/CU-Macky-Tower-SidenoCulling.jpg> <CU-Macky-Tower-SidenoCulling.jpg> <model_4>
<../files/CU-Macky-TowerBasenoCulling.jpg> <CU-Macky-TowerBasenoCulling.jpg> <model_4>
<../files/CU-Macky-TowernoCulling.jpg> <CU-Macky-TowernoCulling.jpg> <model_4>
<../files/CU-Macky-_Side_BrickwallnoCulling.jpg> <CU-Macky-_Side_BrickwallnoCulling.jpg> <model_4>
<../files/roofnoCulling.jpg> <roofnoCulling.jpg> <model_4>

Wyświetl plik

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ViziCities - KML Collada Example</title>
<style type="text/css">
html, body {
height: 100%;
width: 100%;
}
body {
background: #222;
margin: 0;
overflow: hidden;
padding: 0;
}
#vizicities-viewport {
height: 720px;
left: 50%;
margin: -360px 0 0 -640px;
position: absolute;
top: 50%;
width: 1280px;
}
</style>
<link rel="stylesheet" type="text/css" href="../../../build/vizi.css">
</head>
<body>
<div id="vizicities-viewport"></div>
<script src="../../../build/vizi.js"></script>
<script src="main.js"></script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,145 @@
var world = new VIZI.World({
viewport: document.querySelector("#vizicities-viewport"),
center: new VIZI.LatLon(40.01000594412381, -105.2727379358738)
});
var controls = new VIZI.ControlsMap(world.camera, {
viewport: world.options.viewport
});
var colladaConfig = {
input: {
type: "BlueprintInputKML",
options: {
path: "./data/sample.kml"
}
},
output: {
type: "BlueprintOutputCollada",
options: {
modelPathPrefix: "./data/",
infoUI: true
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: [],
actionObject: "input",
actionName: "requestData",
actionArguments: [],
actionOutput: {}
}, {
triggerObject: "input",
triggerName: "dataReceived",
triggerArguments: ["kml"],
actionObject: "output",
actionName: "outputCollada",
actionArguments: ["collada"],
actionOutput: {
collada: {
process: "map",
itemsObject: "kml",
itemsProperties: "placemark.model",
transformation: {
coordinates: ["location.longitude", "location.latitude"],
modelPath: "link.href"
}
}
}
}]
};
var switchboardCollada = new VIZI.BlueprintSwitchboard(colladaConfig);
switchboardCollada.addToWorld(world);
var mapConfig = {
input: {
type: "BlueprintInputMapTiles",
options: {
tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
}
},
output: {
type: "BlueprintOutputImageTiles",
options: {
grids: [{
zoom: 19,
tilesPerDirection: 3,
cullZoom: 17
}, {
zoom: 18,
tilesPerDirection: 3,
cullZoom: 16
}, {
zoom: 17,
tilesPerDirection: 3,
cullZoom: 15
}, {
zoom: 16,
tilesPerDirection: 3,
cullZoom: 14
}, {
zoom: 15,
tilesPerDirection: 3,
cullZoom: 13
}, {
zoom: 14,
tilesPerDirection: 3,
cullZoom: 12
}, {
zoom: 13,
tilesPerDirection: 5,
cullZoom: 11
}]
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "output",
triggerName: "gridUpdated",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "input",
triggerName: "tileReceived",
triggerArguments: ["image", "tile"],
actionObject: "output",
actionName: "outputImageTile",
actionArguments: ["image", "tile"],
actionOutput: {
image: "image", // actionArg: triggerArg
tile: "tile"
}
}]
};
var switchboardMap = new VIZI.BlueprintSwitchboard(mapConfig);
switchboardMap.addToWorld(world);
var clock = new VIZI.Clock();
var update = function() {
var delta = clock.getDelta();
world.onTick(delta);
world.render();
window.requestAnimationFrame(update);
};
update();

Wyświetl plik

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ViziCities - KML Point Example</title>
<style type="text/css">
html, body {
height: 100%;
width: 100%;
}
body {
background: #222;
margin: 0;
overflow: hidden;
padding: 0;
}
#vizicities-viewport {
height: 720px;
left: 50%;
margin: -360px 0 0 -640px;
position: absolute;
top: 50%;
width: 1280px;
}
</style>
<link rel="stylesheet" type="text/css" href="../../../build/vizi.css">
</head>
<body>
<div id="vizicities-viewport"></div>
<script src="../../../build/vizi.js"></script>
<script src="main.js"></script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,140 @@
var world = new VIZI.World({
viewport: document.querySelector("#vizicities-viewport")
});
var controls = new VIZI.ControlsMap(world.camera, {
viewport: world.options.viewport
});
var kmlConfig = {
input: {
type: "BlueprintInputKML",
options: {
path: "./data/sample.kml"
}
},
output: {
type: "BlueprintOutputDebugPoints",
options: {}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: [],
actionObject: "input",
actionName: "requestData",
actionArguments: [],
actionOutput: {}
}, {
triggerObject: "input",
triggerName: "dataReceived",
triggerArguments: ["kml"],
actionObject: "output",
actionName: "outputPoints",
actionArguments: ["data"],
actionOutput: {
data: {
process: "map",
itemsObject: "kml",
itemsProperties: "document.placemark",
transformation: {
coordinates: ["point.coordinates[0]", "point.coordinates[1]"]
}
}
}
}]
};
var switchboardKML = new VIZI.BlueprintSwitchboard(kmlConfig);
switchboardKML.addToWorld(world);
var mapConfig = {
input: {
type: "BlueprintInputMapTiles",
options: {
tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
}
},
output: {
type: "BlueprintOutputImageTiles",
options: {
grids: [{
zoom: 19,
tilesPerDirection: 3,
cullZoom: 17
}, {
zoom: 18,
tilesPerDirection: 3,
cullZoom: 16
}, {
zoom: 17,
tilesPerDirection: 3,
cullZoom: 15
}, {
zoom: 16,
tilesPerDirection: 3,
cullZoom: 14
}, {
zoom: 15,
tilesPerDirection: 3,
cullZoom: 13
}, {
zoom: 14,
tilesPerDirection: 3,
cullZoom: 12
}, {
zoom: 13,
tilesPerDirection: 5,
cullZoom: 11
}]
}
},
triggers: [{
triggerObject: "output",
triggerName: "initialised",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "output",
triggerName: "gridUpdated",
triggerArguments: ["tiles"],
actionObject: "input",
actionName: "requestTiles",
actionArguments: ["tiles"],
actionOutput: {
tiles: "tiles" // actionArg: triggerArg
}
}, {
triggerObject: "input",
triggerName: "tileReceived",
triggerArguments: ["image", "tile"],
actionObject: "output",
actionName: "outputImageTile",
actionArguments: ["image", "tile"],
actionOutput: {
image: "image", // actionArg: triggerArg
tile: "tile"
}
}]
};
var switchboardMap = new VIZI.BlueprintSwitchboard(mapConfig);
switchboardMap.addToWorld(world);
var clock = new VIZI.Clock();
var update = function() {
var delta = clock.getDelta();
world.onTick(delta);
world.render();
window.requestAnimationFrame(update);
};
update();

Wyświetl plik

@ -1,102 +0,0 @@
/*
html5doctor.com Reset Stylesheet
v1.6.1
Last Updated: 2010-09-17
Author: Richard Clark - http://richclarkdesign.com
Twitter: @rich_clark
*/
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin:0;
padding:0;
border:0;
outline:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
}
body {
line-height:1;
}
article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section {
display:block;
}
nav ul {
list-style:none;
}
blockquote, q {
quotes:none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content:'';
content:none;
}
a {
margin:0;
padding:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
}
/* change colours to suit your needs */
ins {
background-color:#ff9;
color:#000;
text-decoration:none;
}
/* change colours to suit your needs */
mark {
background-color:#ff9;
color:#000;
font-style:italic;
font-weight:bold;
}
del {
text-decoration: line-through;
}
abbr[title], dfn[title] {
border-bottom:1px dotted;
cursor:help;
}
table {
border-collapse:collapse;
border-spacing:0;
}
/* change border colour to suit your needs */
hr {
display:block;
height:1px;
border:0;
border-top:1px solid #cccccc;
margin:1em 0;
padding:0;
}
input, select {
vertical-align:middle;
}

Wyświetl plik

@ -1,240 +0,0 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.GeometryExporter = function () {};
THREE.GeometryExporter.prototype = {
constructor: THREE.GeometryExporter,
parse: function ( geometry ) {
var output = {
metadata: {
version: 4.0,
type: 'geometry',
generator: 'GeometryExporter'
}
};
var vertices = [];
for ( var i = 0; i < geometry.vertices.length; i ++ ) {
var vertex = geometry.vertices[ i ];
vertices.push( vertex.x, vertex.y, vertex.z );
}
var faces = [];
var normals = [];
var normalsHash = {};
var colors = [];
var colorsHash = {};
var uvs = [];
var uvsHash = {};
for ( var i = 0; i < geometry.faces.length; i ++ ) {
var face = geometry.faces[ i ];
var isTriangle = face instanceof THREE.Face3;
var hasMaterial = false; // face.materialIndex !== undefined;
var hasFaceUv = false; // deprecated
var hasFaceVertexUv = geometry.faceVertexUvs[ 0 ].length > 0;
var hasFaceNormal = face.normal.length() > 0;
var hasFaceVertexNormal = face.vertexNormals.length > 0;
var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
var hasFaceVertexColor = face.vertexColors.length > 0;
var faceType = 0;
faceType = setBit( faceType, 0, ! isTriangle );
faceType = setBit( faceType, 1, hasMaterial );
faceType = setBit( faceType, 2, hasFaceUv );
faceType = setBit( faceType, 3, hasFaceVertexUv );
faceType = setBit( faceType, 4, hasFaceNormal );
faceType = setBit( faceType, 5, hasFaceVertexNormal );
faceType = setBit( faceType, 6, hasFaceColor );
faceType = setBit( faceType, 7, hasFaceVertexColor );
faces.push( faceType );
if ( isTriangle ) {
faces.push( face.a, face.b, face.c );
} else {
faces.push( face.a, face.b, face.c, face.d );
}
/*
if ( hasMaterial ) {
faces.push( face.materialIndex );
}
*/
if ( hasFaceVertexUv ) {
var faceVertexUvs = geometry.faceVertexUvs[ 0 ][ i ];
if ( isTriangle ) {
faces.push(
getUvIndex( faceVertexUvs[ 0 ] ),
getUvIndex( faceVertexUvs[ 1 ] ),
getUvIndex( faceVertexUvs[ 2 ] )
);
} else {
faces.push(
getUvIndex( faceVertexUvs[ 0 ] ),
getUvIndex( faceVertexUvs[ 1 ] ),
getUvIndex( faceVertexUvs[ 2 ] ),
getUvIndex( faceVertexUvs[ 3 ] )
);
}
}
if ( hasFaceNormal ) {
faces.push( getNormalIndex( face.normal ) );
}
if ( hasFaceVertexNormal ) {
var vertexNormals = face.vertexNormals;
if ( isTriangle ) {
faces.push(
getNormalIndex( vertexNormals[ 0 ] ),
getNormalIndex( vertexNormals[ 1 ] ),
getNormalIndex( vertexNormals[ 2 ] )
);
} else {
faces.push(
getNormalIndex( vertexNormals[ 0 ] ),
getNormalIndex( vertexNormals[ 1 ] ),
getNormalIndex( vertexNormals[ 2 ] ),
getNormalIndex( vertexNormals[ 3 ] )
);
}
}
if ( hasFaceColor ) {
faces.push( getColorIndex( face.color ) );
}
if ( hasFaceVertexColor ) {
var vertexColors = face.vertexColors;
if ( isTriangle ) {
faces.push(
getColorIndex( vertexColors[ 0 ] ),
getColorIndex( vertexColors[ 1 ] ),
getColorIndex( vertexColors[ 2 ] )
);
} else {
faces.push(
getColorIndex( vertexColors[ 0 ] ),
getColorIndex( vertexColors[ 1 ] ),
getColorIndex( vertexColors[ 2 ] ),
getColorIndex( vertexColors[ 3 ] )
);
}
}
}
function setBit( value, position, enabled ) {
return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position) );
}
function getNormalIndex( normal ) {
var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
if ( normalsHash[ hash ] !== undefined ) {
return normalsHash[ hash ];
}
normalsHash[ hash ] = normals.length / 3;
normals.push( normal.x, normal.y, normal.z );
return normalsHash[ hash ];
}
function getColorIndex( color ) {
var hash = color.r.toString() + color.g.toString() + color.b.toString();
if ( colorsHash[ hash ] !== undefined ) {
return colorsHash[ hash ];
}
colorsHash[ hash ] = colors.length;
colors.push( color.getHex() );
return colorsHash[ hash ];
}
function getUvIndex( uv ) {
var hash = uv.x.toString() + uv.y.toString();
if ( uvsHash[ hash ] !== undefined ) {
return uvsHash[ hash ];
}
uvsHash[ hash ] = uvs.length / 2;
uvs.push( uv.x, uv.y );
return uvsHash[ hash ];
}
output.vertices = vertices;
output.normals = normals;
if ( colors.length > 0 ) output.colors = colors;
if ( uvs.length > 0 ) output.uvs = [ uvs ]; // temporal backward compatibility
output.faces = faces;
//
return output;
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

Wyświetl plik

@ -1,29 +1,44 @@
{
"name": "ViziCities",
"version": "0.1.0",
"name": "vizicities",
"version": "0.2.0",
"description": "3D city and data visualisation platform",
"main": "index.js",
"directories": {
"example": "examples",
"test": "test"
},
"scripts": {
"test": "grunt test --verbose"
},
"author": "Robin Hawkes",
"license": "MIT",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.7.0",
"grunt-contrib-uglify": "~0.2.2",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-connect": "~0.5.0",
"grunt-notify": "~0.2.15",
"mocha": "~1.17.1",
"grunt-mocha-phantomjs": "~0.4.0",
"chai": "~1.9.0",
"sinon": "~1.8.1",
"sinon-chai": "~2.5.0"
"repository": {
"type": "git",
"url": "https://github.com/UDST/vizicities.git"
},
"repository" :
{ "type" : "git"
, "url" : "https://github.com/robhawkes/vizicities.git"
"keywords": [
"mapping",
"geography",
"cities",
"urban",
"data",
"dataviz",
"3d"
],
"author": "Robin Hawkes <rob@vizicities.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/UDST/vizicities/issues"
},
"homepage": "https://github.com/UDST/vizicities",
"devDependencies": {
"chai": "^1.9.2",
"grunt": "^0.4.5",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-uglify": "^0.6.0",
"grunt-mocha-slimer": "0.0.2",
"grunt-react": "^0.10.0",
"mocha": "^1.21.5",
"sinon": "^1.10.3",
"sinon-chai": "^2.6.0"
}
}

Wyświetl plik

@ -0,0 +1,264 @@
/* globals window, _, VIZI */
/**
* Tile grid helper
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
// TODO: Define a hole so only tiles outside of that area are used / loaded
VIZI.BlueprintHelperTileGrid = function(world, options) {
if (VIZI.DEBUG) console.log("Initialising VIZI.BlueprintHelperTileGrid");
var self = this;
VIZI.EventEmitter.call(self);
if (!world || !(world instanceof VIZI.World)) {
throw new Error("Required world property missing");
}
self.world = world;
self.options = options || {};
_.defaults(self.options, {});
if (!self.options.zoom) {
throw new Error("Required options zoom property missing");
}
if (!self.options.cullZoom) {
throw new Error("Required options cull zoom property missing");
}
if (self.options.tilesPerDirection === undefined) {
throw new Error("Required options tiles per direction property missing");
}
self.disable = false;
// Location of grid center
self.centerTile = new VIZI.Point();
self.centerTileLatLon = new VIZI.LatLon();
// Tile size and zoom level
self.tileZoom = self.options.zoom;
// Zoom limit before hiding and disabling grid
self.cullZoom = self.options.cullZoom;
// Tiles per direction
self.tilesPerDirection = self.options.tilesPerDirection;
// Calculated pixel tile size
// self.tileSize;
// Grid bounds (in TMS values)
self.bounds;
// Grid bounds (lat, lon)
self.boundsLatLon;
self.tileCount;
// List of tiles, ordered from center outwards
self.tiles = [];
// Grid movement difference since last mouse up
// TODO: Change to something that isn't referencing the mouse as it's no longer used to calculate grid difference.
self.gridDiffSinceMouseUp = new VIZI.Point();
};
VIZI.BlueprintHelperTileGrid.prototype = Object.create( VIZI.EventEmitter.prototype );
// Set up and start grid
// TODO: Immediately disable grid if beyond camera cull point
// What's the best way of getting camera radius to here? Singleton?
VIZI.BlueprintHelperTileGrid.prototype.init = function() {
var self = this;
var coords = self.world.center;
if (VIZI.DEBUG) console.log("coords", coords);
self.centerTile = self.world.crs.latLonToTile(coords, self.tileZoom);
if (VIZI.DEBUG) console.log("centerTile", self.centerTile);
self.centerTileLatLon = new VIZI.LatLon(self.world.center);
if (VIZI.DEBUG) console.log("centerTileLatLon", self.centerTileLatLon);
var centerTileBoundsPoint = self.world.crs.tileBoundsPoint(self.centerTile, self.tileZoom);
if (VIZI.DEBUG) console.log("centerTileBoundsPoint", centerTileBoundsPoint);
self.bounds = self.getBounds(self.tilesPerDirection);
self.boundsLatLon = self.getBoundsLatLon(self.bounds);
if (VIZI.DEBUG) console.log("bounds", self.bounds);
if (VIZI.DEBUG) console.log("boundsLatLon", self.boundsLatLon);
self.tileCount = new VIZI.Point(self.bounds.e - self.bounds.w + 1, self.bounds.s - self.bounds.n + 1);
if (VIZI.DEBUG) console.log("tileCount", self.tileCount);
// REMOVED: Shouldn't be needed any longer as updates are now triggered based on world:updateView events
// TODO: Hook into VIZI.Controls.Mouse or at least use correct DOM element
// Could do with panControlStart and panControlEnd events
// document.body.addEventListener("mouseup", function(event) {
// self.onMouseUp(event);
// }, false);
// TODO: Convert to VIZI.Messenger format
// TODO: Listen for a zoom event from the camera to handle hiding of objects at distance
// self.subscribe("zoomChanged", self.onZoomChanged);
VIZI.Messenger.on("world:updateView", function(center, zoom) {
self.onWorldUpdate(center, zoom);
});
self.collectTiles();
return self.tiles;
};
VIZI.BlueprintHelperTileGrid.prototype.collectTiles = function() {
var self = this;
var tiles = [];
// Rows
for (var i = 0; i < self.tileCount.x; i++) {
// Columns
for (var j = 0; j < self.tileCount.y; j++) {
var tileData = {
x: self.bounds.w + j,
y: self.bounds.n + i,
z: self.tileZoom,
distance: 0,
localCoords: new VIZI.Point()
};
tileData.localCoords = self.globalToLocalTiles(tileData.x, tileData.y);
tileData.distance = Math.abs(self.centerTile.x - tileData.x) + Math.abs(self.centerTile.y - tileData.y);
tiles.push(tileData);
}
}
// Sort tiles by distance from center
tiles.sort(function(a, b) {
if (a.distance < b.distance) {
return -1;
}
if (a.distance > b.distance) {
return 1;
}
return 0;
});
self.tiles = tiles;
};
// Should be covered in VIZI.CRS, just not with the tileDistance bit
VIZI.BlueprintHelperTileGrid.prototype.getBounds = function(tileDistance) {
var self = this;
var bounds = {
n: Math.floor(self.centerTile.y) - tileDistance,
e: Math.ceil(self.centerTile.x) + tileDistance,
s: Math.ceil(self.centerTile.y) + tileDistance,
w: Math.floor(self.centerTile.x) - tileDistance
};
return bounds;
};
// Should be covered in VIZI.CRS, just not with the ability to convert point bounds
VIZI.BlueprintHelperTileGrid.prototype.getBoundsLatLon = function(bounds) {
var self = this;
var max = self.world.crs.tileBoundsLatLon(new VIZI.Point(bounds.e, bounds.n), self.tileZoom);
var min = self.world.crs.tileBoundsLatLon(new VIZI.Point(bounds.w, bounds.s), self.tileZoom);
var boundsLatLon = {
n: max.n,
e: max.e,
s: min.s,
w: min.w
};
return boundsLatLon;
};
// TODO: Move onZoomChanged logic into here
VIZI.BlueprintHelperTileGrid.prototype.onWorldUpdate = function(center, zoom) {
var self = this;
var centerTile = self.world.crs.latLonToTile(center, self.tileZoom);
var gridDiff = new VIZI.Point(
Math.floor(centerTile.x) - Math.floor(self.centerTile.x),
Math.floor(centerTile.y) - Math.floor(self.centerTile.y)
);
if (Math.abs(gridDiff.x) > 0 || Math.abs(gridDiff.y) > 0) {
self.centerTile = centerTile;
self.centerTileLatLon = new VIZI.LatLon(self.world.center);
self.bounds = self.getBounds(self.tilesPerDirection);
self.boundsLatLon = self.getBoundsLatLon(self.bounds);
self.gridDiffSinceMouseUp.x += gridDiff.x;
self.gridDiffSinceMouseUp.y += gridDiff.y;
self.collectTiles();
}
if (zoom < self.cullZoom) {
if (!self.disable) {
// Disable grid
self.disable = true;
self.emit("disabled");
}
} else {
if (self.disable) {
// Enable grid
self.disable = false;
self.emit("enabled");
}
}
// Force an update, even if nothing has changed
self.updateGrid();
};
// REMOVED: Due to move toward using world:updateView instead
// VIZI.BlueprintHelperTileGrid.prototype.onMouseUp = function(event) {
// var self = this;
// self.updateGrid();
// };
VIZI.BlueprintHelperTileGrid.prototype.updateGrid = function() {
var self = this;
// If grid has moved (there's an offset) then move grid mesh and update tiles
// TODO: Change gridDiffSinceMouseUp to something unrelated to mouse
if (Math.abs(self.gridDiffSinceMouseUp.x) > 0 || Math.abs(self.gridDiffSinceMouseUp.y) > 0) {
// self.onGridMove(self.gridDiffSinceMouseUp);
self.emit("moved", self.tiles, self.gridDiffSinceMouseUp);
self.gridDiffSinceMouseUp = new VIZI.Point();
}
};
VIZI.BlueprintHelperTileGrid.prototype.globalToLocalTiles = function(x, y) {
var self = this;
return new VIZI.Point(x - self.bounds.w, y - self.bounds.n);
};
}());

Wyświetl plik

@ -0,0 +1,33 @@
/* globals window, _, VIZI */
/**
* Blueprint input
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
// Automated tasks and complex initialisation are performed in init()
VIZI.BlueprintInput = function(options) {
if (VIZI.DEBUG) console.log("Initialising VIZI.BlueprintInput");
var self = this;
VIZI.EventEmitter.call(self);
self.options = options || {};
// Triggers and actions reference (mostly for GUI hooks)
// [{name: "triggerName", arguments: ["argName1", "argName2"]}, ...]
self.triggers = [];
// [{name: "actionName", arguments: ["argName1", "argName2"]}, ...]
self.actions = [];
};
VIZI.BlueprintInput.prototype = Object.create( VIZI.EventEmitter.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintInput.prototype.init = function() {};
}());

Wyświetl plik

@ -0,0 +1,64 @@
/* globals window, _, VIZI, d3, JXON */
(function() {
"use strict";
/**
* Blueprint GPX input
* @author Robin Hawkes - vizicities.com
*/
// input: {
// type: "BlueprintInputGPX",
// options: {
// path: "/data/sample.gpx"
// }
// }
VIZI.BlueprintInputGPX = function(options) {
var self = this;
VIZI.BlueprintInput.call(self, options);
_.defaults(self.options, {});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []},
{name: "dataReceived", arguments: ["gpx"]}
];
self.actions = [
{name: "requestData", arguments: []}
];
};
VIZI.BlueprintInputGPX.prototype = Object.create( VIZI.BlueprintInput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintInputGPX.prototype.init = function() {
var self = this;
self.emit("initialised");
};
// TODO: Pull from cache if available
VIZI.BlueprintInputGPX.prototype.requestData = function(tiles) {
var self = this;
if (!self.options.path) {
throw new Error("Required path option missing");
}
// Request data
d3.xml(self.options.path, function(error, data) {
if (error) {
if (VIZI.DEBUG) console.log("Failed to request GPX data");
console.warn(error);
return;
}
// Process GPX into a JSON format
var jxon = JXON.build(data.querySelector("gpx"));
self.emit("dataReceived", jxon);
});
};
}());

Wyświetl plik

@ -0,0 +1,104 @@
/* globals window, _, VIZI, d3 */
(function() {
"use strict";
/**
* Blueprint GeoJSON input
* @author Robin Hawkes - vizicities.com
*/
// input: {
// type: "BlueprintInputGeoJSON",
// options: {
// path: "/data/tower-hamlets-lsoa-census.geojson"
// // tilePath: "http://vector.mapzen.com/osm/buildings/{z}/{x}/{y}.json"
// }
// }
var tileURLRegex = /\{([zxy])\}/g;
VIZI.BlueprintInputGeoJSON = function(options) {
var self = this;
VIZI.BlueprintInput.call(self, options);
_.defaults(self.options, {});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []},
{name: "dataReceived", arguments: ["geoJSON"]},
{name: "tileReceived", arguments: ["geoJSON", "tile"]}
];
self.actions = [
{name: "requestData", arguments: []},
{name: "requestTiles", arguments: ["tiles"]}
];
};
VIZI.BlueprintInputGeoJSON.prototype = Object.create( VIZI.BlueprintInput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintInputGeoJSON.prototype.init = function() {
var self = this;
self.emit("initialised");
};
// TODO: Pull from cache if available
VIZI.BlueprintInputGeoJSON.prototype.requestData = function() {
var self = this;
if (!self.options.path) {
throw new Error("Required path option missing");
}
// Request data
d3.json(self.options.path, function(error, data) {
if (error) {
if (VIZI.DEBUG) console.log("Failed to request GeoJSON data");
console.warn(error);
return;
}
self.emit("dataReceived", data);
});
};
// [{
// x: 262116,
// y: 174348,
// z: 19
// }, ...]
// TODO: Cache a certain amount of tiles
// TODO: Pull from cache if available
VIZI.BlueprintInputGeoJSON.prototype.requestTiles = function(tiles) {
var self = this;
if (!self.options.tilePath) {
throw new Error("Required tile path option missing");
}
if (VIZI.DEBUG) console.log("Requesting tiles", tiles);
_.each(tiles, function(tile, key) {
tileURLRegex.lastIndex = 0;
var url = self.options.tilePath.replace(tileURLRegex, function(value, key) {
// Replace with paramter, otherwise keep existing value
return tile[key];
});
// Request tile data
d3.json(url, function(error, data) {
if (error) {
if (VIZI.DEBUG) console.log("Failed to request GeoJSON data");
console.warn(error);
return;
}
self.emit("tileReceived", data, tile);
});
});
};
}());

Wyświetl plik

@ -0,0 +1,83 @@
/* globals window, _, VIZI, d3, JXON */
(function() {
"use strict";
/**
* Blueprint KML input
* @author Robin Hawkes - vizicities.com
*/
// input: {
// type: "BlueprintInputKML",
// options: {
// path: "/data/tower-hamlets.kml"
// }
// }
VIZI.BlueprintInputKML = function(options) {
var self = this;
VIZI.BlueprintInput.call(self, options);
_.defaults(self.options, {});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []},
{name: "dataReceived", arguments: ["kml"]}
];
self.actions = [
{name: "requestData", arguments: []}
];
};
VIZI.BlueprintInputKML.prototype = Object.create( VIZI.BlueprintInput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintInputKML.prototype.init = function() {
var self = this;
self.emit("initialised");
};
// TODO: Cache a certain amount of tiles
// TODO: Pull from cache if available
VIZI.BlueprintInputKML.prototype.requestData = function(tiles) {
var self = this;
if (!self.options.path) {
throw new Error("Required path option missing");
}
// Request data
d3.xml(self.options.path, function(error, data) {
if (error) {
if (VIZI.DEBUG) console.log("Failed to request KML data");
console.warn(error);
return;
}
// Process KML into a JSON format
var jxon = JXON.build(data.querySelector("kml"));
// Process coordinates
self.processCoordinates(jxon);
self.emit("dataReceived", jxon);
});
};
// Process coordinates from KML string "lon,lat,alt" into an expected array [lon, lat, alt]
// https://developers.google.com/kml/documentation/kmlreference
// TODO: Handle multi-line coordinates (eg. the Polygon type)
VIZI.BlueprintInputKML.prototype.processCoordinates = function(obj) {
var self = this;
_.each(obj, function(item, index) {
if (_.isObject(item)) {
self.processCoordinates(item);
} else if (index === "coordinates") {
obj[index] = item.split(",");
}
});
};
}());

Wyświetl plik

@ -0,0 +1,76 @@
/* globals window, _, VIZI */
(function() {
"use strict";
/**
* Blueprint map tiles input
* @author Robin Hawkes - vizicities.com
*/
// input: {
// type: "BlueprintInputMapTiles",
// options: {
// tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
// }
// }
var tileURLRegex = /\{([zxy])\}/g;
VIZI.BlueprintInputMapTiles = function(options) {
var self = this;
VIZI.BlueprintInput.call(self, options);
_.defaults(self.options, {
tilePath: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}@2x.png"
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []},
{name: "tileReceived", arguments: ["image", "tile"]}
];
self.actions = [{name: "requestTiles", arguments: ["tiles"]}];
};
VIZI.BlueprintInputMapTiles.prototype = Object.create( VIZI.BlueprintInput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintInputMapTiles.prototype.init = function() {
var self = this;
self.emit("initialised");
};
// [{
// x: 262116,
// y: 174348,
// z: 19
// }, ...]
// TODO: Pull from cache if available
// TODO: Cache a certain amount of tiles
VIZI.BlueprintInputMapTiles.prototype.requestTiles = function(tiles) {
var self = this;
if (VIZI.DEBUG) console.log("Requesting tiles", tiles);
_.each(tiles, function(tile, key) {
tileURLRegex.lastIndex = 0;
var url = self.options.tilePath.replace(tileURLRegex, function(value, key) {
// Replace with paramter, otherwise keep existing value
return tile[key];
});
var img = new Image();
img.onload = function() {
self.emit("tileReceived", img, tile);
img = undefined;
};
img.crossOrigin = "Anonymous";
img.src = url;
});
};
}());

Wyświetl plik

@ -0,0 +1,44 @@
/* globals window, _, VIZI */
/**
* Blueprint output
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
// Automated tasks and complex initialisation are performed in init()
VIZI.BlueprintOutput = function(options) {
if (VIZI.DEBUG) console.log("Initialising VIZI.BlueprintOutput");
var self = this;
VIZI.Layer.call(self);
self.options = options || {};
_.defaults(self.options, {
description: ""
});
// Triggers and actions reference (mostly for GUI hooks)
// [{name: "triggerName", arguments: ["argName1", "argName2"]}, ...]
self.triggers = [];
// [{name: "actionName", arguments: ["argName1", "argName2"]}, ...]
self.actions = [];
self.name = "";
self.description = self.options.description;
// TODO: How do you ensure the layer abides by fustrum culling when inner objects are referencing the world coordinate space
// self.layer = new VIZI.Layer();
};
VIZI.BlueprintOutput.prototype = Object.create( VIZI.Layer.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutput.prototype.init = function() {};
VIZI.BlueprintOutput.prototype.onTick = function(delta) {};
}());

Wyświetl plik

@ -0,0 +1,373 @@
/* globals window, _, VIZI, THREE, operative */
(function() {
"use strict";
/**
* Blueprint building tiles output
* @author Robin Hawkes - vizicities.com
*/
// output: {
// type: "BlueprintOutputBuildingTiles",
// options: {
// grids: [{
// zoom: 19,
// tilesPerDirection: 3,
// cullZoom: 15
// },
// ...
// }
// }
VIZI.BlueprintOutputBuildingTiles = function(options) {
var self = this;
VIZI.BlueprintOutput.call(self, options);
_.defaults(self.options, {
materialType: "MeshLambertMaterial",
materialOptions: {},
workerURL: "vizi-worker.min.js",
name: "Building tiles"
});
_.defaults(self.options.materialOptions, {
color: 0xeeeeee,
ambient: 0xffffff,
emissive: 0xcccccc,
shading: THREE.FlatShading
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: ["tiles"]},
{name: "gridUpdated", arguments: ["tiles", "newTiles"]}
];
self.actions = [
{name: "outputBuildingTile", arguments: ["buildings", "tile"]}
];
self.name = self.options.name;
// Grids
// {16: {
// grid: VIZI.BlueprintHelperTileGrid,
// mesh: THREE.Object3D
// }, ...}
self.grids = {};
self.world;
self.worker;
};
VIZI.BlueprintOutputBuildingTiles.prototype = Object.create( VIZI.BlueprintOutput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutputBuildingTiles.prototype.init = function() {
var self = this;
self.worker = operative(self.outputBuildingTileWorker, [
self.options.workerURL
]);
// Create grids
_.each(self.options.grids, function(grid) {
self.grids[grid.zoom] = self.createGrid(grid);
});
var combinedTiles = [];
_.each(self.grids, function(gridHash) {
combinedTiles = combinedTiles.concat(gridHash.grid.tiles);
});
self.emit("initialised", combinedTiles);
};
VIZI.BlueprintOutputBuildingTiles.prototype.createGrid = function(gridOptions) {
var self = this;
var gridOutput = {};
var grid = new VIZI.BlueprintHelperTileGrid(self.world, gridOptions);
grid.on("moved", function(tiles, diff) {
if (VIZI.DEBUG) console.log("Grid moved", tiles, diff);
// TODO: Check whether this is enough to remove references to the old mesh
var oldMeshes = gridOutput.meshes;
var newTiles = [];
gridOutput.meshes = {};
tiles.forEach(function (tile) {
var key = tile.x + '/' + tile.y;
if (oldMeshes.hasOwnProperty(key)) {
gridOutput.meshes[key] = oldMeshes[key];
delete oldMeshes[key];
} else {
newTiles.push(tile);
}
});
// TODO: Animate building heights before removing them
_.forEach(oldMeshes, function (mesh) {
self.remove(mesh);
});
// Only emit update event if grid is enabled
if (!grid.disable) {
self.emit("gridUpdated", tiles, newTiles);
}
});
grid.on("disabled", function() {
if (VIZI.DEBUG) console.log("Grid disabled");
_.each(gridOutput.meshes, function(mesh) {
mesh.visible = false;
});
});
// TODO: Either remove previous tiles or prevent event if grid hasn't moved
// There's a huge hang-up when zooming in due to re-loading and processing tiles
grid.on("enabled", function() {
if (VIZI.DEBUG) console.log("Grid enabled");
self.emit("gridUpdated", grid.tiles);
// TODO: Animate building heights when making them visible again
_.each(gridOutput.meshes, function(mesh) {
mesh.visible = true;
});
});
var tiles = grid.init();
if (VIZI.DEBUG) console.log("Grid initialised", tiles);
gridOutput.grid = grid;
gridOutput.meshes = {};
return gridOutput;
};
// Building
// {
// outline: [[outerCoords], [innerCoords], [innerCoords], ...],
// height: 123
// }
// TODO: Cache processed tile
// TODO: Use cached tile if available
// TODO: Animate building heights on load
VIZI.BlueprintOutputBuildingTiles.prototype.outputBuildingTile = function(buildings, tile) {
if (!buildings.length) {
return;
}
var self = this;
// Find grid
var gridHash = self.grids[tile.z];
var tileKey = tile.x + '/' + tile.y;
if (gridHash.meshes[tileKey]) {
// This mesh is already loaded
return;
}
var materialType = self.options.materialType;
if (!materialType || typeof THREE[materialType] !== "function") {
materialType = "MeshLambertMaterial";
}
var material = new THREE[materialType](self.options.materialOptions);
// Load buildings in a Web Worker
self.worker(self.world.origin, self.world.originZoom, self.options, buildings).then(function(result) {
var offset = result.offset;
var geom = new THREE.BufferGeometry();
geom.addAttribute('position', new THREE.BufferAttribute(result.position, 3));
geom.addAttribute('normal', new THREE.BufferAttribute(result.normal, 3));
geom.addAttribute('uv', new THREE.BufferAttribute(result.uv, 2));
var mesh = new THREE.Mesh(geom, material);
// Use previously calculated offset to return merged mesh to correct position
// This allows frustum culling to work correctly
mesh.position.x = -1 * offset.x;
mesh.position.y = -1 * offset.y;
mesh.position.z = -1 * offset.z;
gridHash.meshes[tileKey] = mesh;
// TODO: Make sure coordinate space is right
self.add(mesh);
}, function(failure) {
// ...
});
};
// TODO: Is this running before the Blueprint is initialised and taking up unnecessary memory?
// TODO: Find a better way to replicate World state (origin, origin zoom, CRS, etc) so it doesn't have to be duplicated for every Blueprint
VIZI.BlueprintOutputBuildingTiles.prototype.outputBuildingTileWorker = function(origin, originZoom, options, buildings) {
var self = this;
var deferred = self.deferred();
// Set up CRS to replicate main thread
var crs = VIZI.CRS.EPSG3857;
// Proxy world project (normal project - world origin)
// TODO: Find a better way so this doesn't have to be duplicated for every Blueprint
var project = function(latLon, zoom) {
zoom = zoom || originZoom;
// TODO: Are there ramifications to rounding the pixels?
var originPoint = crs.latLonToPoint(origin, zoom, {round: true});
var projected = crs.latLonToPoint(latLon, zoom, {round: true});
return projected.clone().subtract(originPoint);
};
// Proxy world pixelPerMeter
// TODO: Find a better way so this doesn't have to be duplicated for every Blueprint
var pixelsPerMeter = function(latLon, zoom) {
zoom = zoom || originZoom;
return crs.pixelsPerMeter(latLon, zoom);
};
var combinedGeom = new THREE.Geometry();
// TODO: Remove manual, hard-baked height-related stuff
var metersPerLevel = 3;
// TODO: Remove forced office scaling
var scalingFactor = 1.45;
// var scalingFactor = (tags["building"] === "office") ? 1.45 : 1;
// Local pixels per meter - set once per tile
var ppm;
_.each(buildings, function(feature) {
var offset = new VIZI.Point();
var shape = new THREE.Shape();
var outer = feature.outline.shift();
var inners = feature.outline;
// Quick check to see if we have a valid polygon to work with
if (typeof outer !== "object") {
return;
}
// Create outer shape
_.each(outer, function(coord, index) {
var latLon = new VIZI.LatLon(coord[1], coord[0]);
var geoCoord = project(latLon);
// Set local pixels per meter if not set
if (ppm === undefined) {
ppm = pixelsPerMeter(latLon);
}
if (offset.length === 0) {
offset.x = -1 * geoCoord.x;
offset.y = -1 * geoCoord.y;
}
// Move if first coordinate
if (index === 0) {
shape.moveTo( geoCoord.x + offset.x, geoCoord.y + offset.y );
} else {
shape.lineTo( geoCoord.x + offset.x, geoCoord.y + offset.y );
}
});
// Create inner shapes (holes)
_.each(inners, function(inner, index) {
var innerPath = new THREE.Path();
_.each(inner, function(coord, index) {
var latLon = new VIZI.LatLon(coord[1], coord[0]);
var geoCoord = project(latLon);
// Move if first coordinate
if (index === 0) {
innerPath.moveTo( geoCoord.x + offset.x, geoCoord.y + offset.y );
} else {
innerPath.lineTo( geoCoord.x + offset.x, geoCoord.y + offset.y );
}
});
shape.holes.push(innerPath);
});
// TODO: Don't have random height logic in here
var height = (feature.height) ? feature.height : 5 + Math.random() * 10;
var minHeight = (feature.minHeight) ? feature.minHeight : 0;
// TODO: Add floor/level-based heights
// << rounds the height down
// var height = (feature.height * metersPerLevel * scalingFactor << 0);
// Multiply height in meters by pixels per meter ratio at latitude
height *= ppm.y;
minHeight *= ppm.y;
var extrudeSettings = { amount: height - minHeight, bevelEnabled: false };
var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
geom.computeFaceNormals();
if (!minHeight && !options.preserveGroundFaces) {
// Remove down-facing floor faces
for (var i = geom.faces.length - 1; i >= 0; i--) {
if (Math.abs(geom.faces[i].normal.z - 1) < Number.EPSILON) {
geom.faces.splice(i, 1);
geom.faceVertexUvs[0].splice(i, 1);
}
}
}
var mesh = new THREE.Mesh(geom);
mesh.position.y = height;
// Offset
mesh.position.x = -1 * offset.x;
mesh.position.z = -1 * offset.y;
// Flip as they are up-side down
mesh.rotation.x = 90 * Math.PI / 180;
mesh.matrixAutoUpdate && mesh.updateMatrix();
combinedGeom.merge(mesh.geometry, mesh.matrix);
});
// Move merged geom to 0,0 and return offset
var offset = combinedGeom.center();
//TODO: save a more compact model using indices. Requires replacing fromGeometry with custom code
var exportedGeom = new THREE.BufferGeometry();
exportedGeom.fromGeometry(combinedGeom);
// Store geom typed array as Three.js model object
var model = {
offset: offset
};
var transfers = [];
exportedGeom.attributesKeys.forEach(function (key) {
model[key] = exportedGeom.attributes[key].array;
transfers.push(model[key].buffer);
});
deferred.transferResolve(model, transfers);
};
VIZI.BlueprintOutputBuildingTiles.prototype.onAdd = function(world) {
var self = this;
self.world = world;
self.init();
};
}());

Wyświetl plik

@ -0,0 +1,320 @@
/* globals window, _, VIZI, d3, THREE */
(function() {
"use strict";
/**
* Blueprint choropleth output
* @author Robin Hawkes - vizicities.com
*/
// TODO: Animate hover and off effect for picking (opacity, scale, etc)
// TODO: Show 2D info UI on hover or click
// output: {
// type: "BlueprintOutputChoropleth",
// options: {
// colourRange: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],
// layer: 100
// }
// }
VIZI.BlueprintOutputChoropleth = function(options) {
var self = this;
VIZI.BlueprintOutput.call(self, options);
_.defaults(self.options, {
colourRange: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],
layer: 10,
keyUI: true,
infoUI: false,
name: "Choropleth"
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []}
];
self.actions = [
{name: "outputChoropleth", arguments: ["data"]}
];
self.name = self.options.name;
self.world;
self.keyUI;
self.infoUI;
self.pickedMesh;
self.lastPickedIdClick;
};
VIZI.BlueprintOutputChoropleth.prototype = Object.create( VIZI.BlueprintOutput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutputChoropleth.prototype.init = function() {
var self = this;
// Set up key UI
if (self.options.keyUI) {
self.keyUI = new VIZI.KeyUIColourScale(self);
}
// Set up info UI
if (self.options.infoUI) {
self.infoUI = new VIZI.InfoUI2D(self.world);
}
self.emit("initialised");
};
// {
// outline: [],
// value: 123
// }
VIZI.BlueprintOutputChoropleth.prototype.outputChoropleth = function(data) {
var self = this;
var material = new THREE.MeshLambertMaterial({
vertexColors: THREE.VertexColors,
ambient: 0xffffff,
emissive: 0xcccccc,
shading: THREE.FlatShading,
// TODO: Remove this by implementing logic to make points clockwise
side: THREE.BackSide
});
// Choropleth range settings
if (self.options.colourRange) {
// Sort feature data in order
var dataValues = data.sort(function(a, b) {
return d3.ascending(Number(a.value), Number(b.value));
});
var lo = Number(dataValues[0].value);
var hi = Number(dataValues[data.length - 1].value);
// TODO: Decouple range values
var scale = d3.scale.linear()
.domain([lo, hi])
.range([1, 500]);
var scaleColour = d3.scale.quantile()
.domain([lo, hi])
.range(self.options.colourRange);
var breakCount = scaleColour.range().length;
var keyScale = scaleColour.range().map(function(value, index) {
var key;
if (index === 0) {
key = Number(lo.toFixed(2)) + " - " + Number(scaleColour.quantiles()[index].toFixed(2));
} else if (index === breakCount - 1) {
key = Number(scaleColour.quantiles()[index-1].toFixed(2)) + " - " + Number(hi.toFixed(2));
} else {
key = Number(scaleColour.quantiles()[index-1].toFixed(2)) + " - " + Number(scaleColour.quantiles()[index].toFixed(2));
}
return {
colour: value,
key: key
}
});
if (self.keyUI) {
self.keyUI.scale = keyScale;
self.keyUI.onChange();
}
}
var combinedGeom = new THREE.Geometry();
_.each(data, function(feature) {
var offset = new VIZI.Point();
var shape = new THREE.Shape();
_.each(feature.outline, function(coord, index) {
var geoCoord = self.world.project(new VIZI.LatLon(coord[1], coord[0]));
if (offset.length === 0) {
offset.x = -1 * geoCoord.x;
offset.y = -1 * geoCoord.y;
}
// Move if first coordinate
if (index === 0) {
shape.moveTo( geoCoord.x + offset.x, geoCoord.y + offset.y );
} else {
shape.lineTo( geoCoord.x + offset.x, geoCoord.y + offset.y );
}
});
var geom = new THREE.ShapeGeometry( shape );
// Use choropleth range colour if defined, else random
var colour = (self.options.colourRange) ? new THREE.Color(scaleColour(feature.value)) : new THREE.Color(0xffffff * Math.random());
self.applyVertexColors(geom, colour);
var mesh = new THREE.Mesh(geom);
// Offset
mesh.position.x = -1 * offset.x;
mesh.position.z = -1 * offset.y;
// TODO: Provide Y offset in options (to avoid clashing with floor, etc)
// mesh.position.y = 1;
// Flip as they are up-side down
// TODO: Remove this by implementing logic to make points clockwise
mesh.rotation.x = 90 * Math.PI / 180;
mesh.matrixAutoUpdate && mesh.updateMatrix();
combinedGeom.merge(mesh.geometry, mesh.matrix);
// Make choropleth element clickable
// TODO: Should this reference the geom.id or mesh.id?
self.world.addPickable(mesh, geom.id);
VIZI.Messenger.on("pick-hover:" + geom.id, function() {
// Do nothing if hidden
if (self.hidden) {
return;
}
if (self.pickedMesh) {
self.remove(self.pickedMesh);
}
var geomCopy = geom.clone();
self.pickedMesh = new THREE.Mesh(geomCopy, new THREE.MeshBasicMaterial({
color: 0xff0000,
// TODO: Remove this by implementing logic to make points clockwise
side: THREE.BackSide,
depthWrite: false,
transparent: true
}));
var offset = geomCopy.center();
// Use previously calculated offset to return merged mesh to correct position
// This allows frustum culling to work correctly
self.pickedMesh.position.x = -1 * offset.x;
// Removed for scale center to be correct
// Offset with applyMatrix above
self.pickedMesh.position.y = -1 * offset.z;
// TODO: Why is Y the Z offset here?
// Is it because the choropleth objects are flipped at 90 degrees?
self.pickedMesh.position.z = -1 * offset.y;
// self.pickedMesh.position.copy(mesh.position);
self.pickedMesh.rotation.copy(mesh.rotation);
self.pickedMesh.scale.copy(mesh.scale);
self.pickedMesh.renderDepth = -1.1 * self.options.layer;
self.pickedMesh.matrixAutoUpdate && self.pickedMesh.updateMatrix();
self.add(self.pickedMesh);
});
VIZI.Messenger.on("pick-off:" + geom.id, function() {
if (self.pickedMesh) {
self.remove(self.pickedMesh);
}
});
VIZI.Messenger.on("pick-click:" + geom.id, function() {
// Do nothing if hidden
if (self.hidden) {
return;
}
// console.log("Clicked:", geom.id);
var pickedId;
// Create info panel
if (self.infoUI) {
if (self.lastPickedIdClick) {
self.infoUI.removePanel(self.lastPickedIdClick);
pickedId = undefined;
}
if (!self.lastPickedIdClick || self.lastPickedIdClick !== self.pickedMesh.id) {
self.infoUI.addPanel(self.pickedMesh, feature.value);
pickedId = self.pickedMesh.id;
}
}
self.lastPickedIdClick = pickedId;
});
});
// Move merged geom to 0,0 and return offset
var offset = combinedGeom.center();
var combinedMesh = new THREE.Mesh(combinedGeom, material);
if (self.options.layer.toString().length > 0) {
combinedMesh.renderDepth = -1 * self.options.layer;
combinedMesh.material.depthWrite = false;
combinedMesh.material.transparent = true;
}
// Use previously calculated offset to return merged mesh to correct position
// This allows frustum culling to work correctly
combinedMesh.position.x = -1 * offset.x;
// Removed for scale center to be correct
// Offset with applyMatrix above
combinedMesh.position.y = -1 * offset.y;
combinedMesh.position.z = -1 * offset.z;
self.add(combinedMesh);
};
VIZI.BlueprintOutputChoropleth.prototype.onHide = function() {
var self = this;
if (self.keyUI) {
self.keyUI.onHide();
}
if (self.infoUI) {
self.infoUI.onHide();
}
};
VIZI.BlueprintOutputChoropleth.prototype.onShow = function() {
var self = this;
if (self.keyUI) {
self.keyUI.onShow();
}
if (self.infoUI) {
self.infoUI.onShow();
}
};
VIZI.BlueprintOutputChoropleth.prototype.onTick = function(delta) {
var self = this;
// Update panel positions
// TODO: Work out how to remove the visible lag between panel position
// and actual scene / camera position.
if (self.infoUI) {
self.infoUI.onChange();
}
}
VIZI.BlueprintOutputChoropleth.prototype.onAdd = function(world) {
var self = this;
self.world = world;
self.init();
};
}());

Wyświetl plik

@ -0,0 +1,139 @@
/* globals window, _, VIZI, d3, THREE */
(function() {
"use strict";
/**
* Blueprint collada output
* @author Robin Hawkes - vizicities.com
*/
// output: {
// type: "BlueprintOutputCollada",
// options: {
// modelPathPrefix: "/data/kml-model/"
// }
// }
VIZI.BlueprintOutputCollada = function(options) {
var self = this;
VIZI.BlueprintOutput.call(self, options);
_.defaults(self.options, {
infoUI: false,
name: "Collada"
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []}
];
self.actions = [
{name: "outputCollada", arguments: ["collada"]}
];
self.name = self.options.name;
self.world;
self.infoUI;
};
VIZI.BlueprintOutputCollada.prototype = Object.create( VIZI.BlueprintOutput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutputCollada.prototype.init = function() {
var self = this;
// Set up info UI
if (self.options.infoUI) {
self.infoUI = new VIZI.InfoUI2D(self.world);
}
self.emit("initialised");
};
// TODO: Process collada import and mesh generation in a Web Worker
// TODO: Throttle requests for collada files
VIZI.BlueprintOutputCollada.prototype.outputCollada = function(data) {
var self = this;
// TODO: Remove this hack around THREE.Loader.Handlers
// THREE.Loader.Handlers = {get: function(){ return null; }};
// Local pixels per meter - set once per tile
var pixelsPerMeter;
_.each(data, function(item) {
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
var path = (self.options.modelPathPrefix) ? self.options.modelPathPrefix + item.modelPath : item.modelPath;
loader.load(path, function (collada) {
var dae = collada.scene;
var latLon = new VIZI.LatLon(item.coordinates[1], item.coordinates[0]);
var geoCoord = self.world.project(latLon);
// Set local pixels per meter if not set
if (pixelsPerMeter === undefined) {
pixelsPerMeter = self.world.pixelsPerMeter(latLon);
}
// Move to correct position
dae.position.x = geoCoord.x;
dae.position.z = geoCoord.y;
// Scale value below 1 indicates collada units are in metres
// https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/ColladaLoader.js#L219
// if (dae.scale.x < 1) {
// Scale up model from meters to pixels
dae.scale.x = dae.scale.y = dae.scale.z = dae.scale.x * pixelsPerMeter.y;
dae.updateMatrix();
// }
self.add(dae);
// Create info panel
// TODO: Work out a way to pass in custom text for the info panel or
// make it obvcious that you can only use the data avaiable.
if (self.infoUI) {
self.infoUI.addPanel(dae, dae.id);
}
});
});
};
VIZI.BlueprintOutputCollada.prototype.onTick = function(delta) {
var self = this;
// Update panel positions
// TODO: Work out how to remove the visible lag between panel position
// and actual scene / camera position.
if (self.infoUI) {
self.infoUI.onChange();
}
}
VIZI.BlueprintOutputCollada.prototype.onHide = function() {
var self = this;
if (self.infoUI) {
self.infoUI.onHide();
}
};
VIZI.BlueprintOutputCollada.prototype.onShow = function() {
var self = this;
if (self.infoUI) {
self.infoUI.onShow();
}
};
VIZI.BlueprintOutputCollada.prototype.onAdd = function(world) {
var self = this;
self.world = world;
self.init();
};
}());

Wyświetl plik

@ -0,0 +1,91 @@
/* globals window, _, VIZI, THREE */
(function() {
"use strict";
/**
* Blueprint debug lines output
* @author Robin Hawkes - vizicities.com
*/
// output: {
// type: "BlueprintOutputDebugLines",
// options: {}
// }
VIZI.BlueprintOutputDebugLines = function(options) {
var self = this;
VIZI.BlueprintOutput.call(self, options);
_.defaults(self.options, {
name: "Debug lines"
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []}
];
self.actions = [
{name: "outputLines", arguments: ["data"]}
];
self.name = self.options.name;
self.world;
};
VIZI.BlueprintOutputDebugLines.prototype = Object.create( VIZI.BlueprintOutput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutputDebugLines.prototype.init = function() {
var self = this;
self.emit("initialised");
};
// {
// coordinates: [lon, lat],
// height: 123
// }
VIZI.BlueprintOutputDebugLines.prototype.outputLines = function(data) {
var self = this;
var material = new THREE.LineBasicMaterial({
color: 0xff0000,
linewidth: 3
});
var geom = new THREE.Geometry();
// Local pixels per meter - set once per tile
var pixelsPerMeter;
_.each(data, function(point) {
var latLon = new VIZI.LatLon(point.coordinates[1], point.coordinates[0]);
var geoCoord = self.world.project(latLon);
// Set local pixels per meter if not set
if (pixelsPerMeter === undefined) {
pixelsPerMeter = self.world.pixelsPerMeter(latLon);
}
// TODO: Get this from options
var height = point.height || 10;
// Multiply height in meters by pixels per meter ratio at latitude
height *= pixelsPerMeter.y;
geom.vertices.push(new THREE.Vector3( geoCoord.x, height, geoCoord.y ));
});
var line = new THREE.Line( geom, material );
self.add(line);
};
VIZI.BlueprintOutputDebugLines.prototype.onAdd = function(world) {
var self = this;
self.world = world;
self.init();
};
}());

Wyświetl plik

@ -0,0 +1,122 @@
/* globals window, _, VIZI, THREE */
(function() {
"use strict";
/**
* Blueprint debug points output
* @author Robin Hawkes - vizicities.com
*/
// output: {
// type: "BlueprintOutputDebugPoints",
// options: {}
// }
VIZI.BlueprintOutputDebugPoints = function(options) {
var self = this;
VIZI.BlueprintOutput.call(self, options);
_.defaults(self.options, {
name: "Debug points"
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: []}
];
self.actions = [
{name: "outputPoints", arguments: ["data"]}
];
self.name = self.options.name;
self.world;
};
VIZI.BlueprintOutputDebugPoints.prototype = Object.create( VIZI.BlueprintOutput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutputDebugPoints.prototype.init = function() {
var self = this;
self.emit("initialised");
};
// {
// coordinates: [lon, lat]
// }
VIZI.BlueprintOutputDebugPoints.prototype.outputPoints = function(data) {
var self = this;
var material = new THREE.MeshBasicMaterial({
color: 0xff0000,
// vertexColors: THREE.VertexColors,
// ambient: 0xffffff,
// emissive: 0xcccccc,
shading: THREE.FlatShading
});
var barGeom = new THREE.BoxGeometry( 40, 1, 40 );
// Shift each vertex by half the bar height
// This means it will scale from the bottom rather than the centre
var vertices = barGeom.vertices;
for (var v = 0; v < vertices.length; v++) {
vertices[v].y += 0.5;
}
var combinedGeom = new THREE.Geometry();
_.each(data, function(point) {
var coords = point.coordinates;
var offset = new VIZI.Point();
var geoCoord = self.world.project(new VIZI.LatLon(coords[1], coords[0]));
offset.x = -1 * geoCoord.x;
offset.y = -1 * geoCoord.y;
// TODO: Get this from options
var height = 1000;
var mesh = new THREE.Mesh(barGeom);
mesh.scale.y = height;
// Offset
mesh.position.x = -1 * offset.x;
mesh.position.z = -1 * offset.y;
// Flip as they are up-side down
// mesh.rotation.x = 90 * Math.PI / 180;
mesh.matrixAutoUpdate && mesh.updateMatrix();
combinedGeom.merge(mesh.geometry, mesh.matrix);
});
// Move merged geom to 0,0 and return offset
var offset = combinedGeom.center();
var combinedMesh = new THREE.Mesh(combinedGeom, material);
// Use previously calculated offset to return merged mesh to correct position
// This allows frustum culling to work correctly
combinedMesh.position.x = -1 * offset.x;
// Removed for scale center to be correct
// Offset with applyMatrix above
combinedMesh.position.y = -1 * offset.y;
combinedMesh.position.z = -1 * offset.z;
self.add(combinedMesh);
};
VIZI.BlueprintOutputDebugPoints.prototype.onAdd = function(world) {
var self = this;
self.world = world;
self.init();
};
}());

Wyświetl plik

@ -0,0 +1,274 @@
/* globals window, _, VIZI, THREE */
(function() {
"use strict";
/**
* Blueprint image tiles output
* @author Robin Hawkes - vizicities.com
*/
// output: {
// type: "BlueprintOutputImageTiles",
// options: {
// grids: [{
// zoom: 19,
// tilesPerDirection: 3,
// cullZoom: 17
// },
// ...
// }
// }
VIZI.BlueprintOutputImageTiles = function(options) {
var self = this;
VIZI.BlueprintOutput.call(self, options);
_.defaults(self.options, {
materialType: "MeshBasicMaterial",
materialOptions: {},
name: "Image tiles"
});
_.defaults(self.options.materialOptions, {
// color: 0x00FF00,
depthWrite: false,
transparent: true
});
// Triggers and actions reference
self.triggers = [
{name: "initialised", arguments: ["tiles"]},
{name: "gridUpdated", arguments: ["tiles"]}
];
self.actions = [
{name: "outputImageTile", arguments: ["image", "tile"]}
];
self.name = self.options.name;
// Grids
// {16: {
// grid: VIZI.BlueprintHelperTileGrid,
// canvas: DOMCanvas,
// canvasSizeDiff: Float,
// context: CanvasContext,
// mesh: THREE.Object3D
// }, ...}
self.grids = {};
self.world;
};
VIZI.BlueprintOutputImageTiles.prototype = Object.create( VIZI.BlueprintOutput.prototype );
// Initialise instance and start automated processes
VIZI.BlueprintOutputImageTiles.prototype.init = function() {
var self = this;
// Create grids
_.each(self.options.grids, function(grid) {
self.grids[grid.zoom] = self.createGrid(grid);
});
var combinedTiles = [];
_.each(self.grids, function(gridHash) {
combinedTiles = combinedTiles.concat(gridHash.grid.tiles);
});
self.emit("initialised", combinedTiles);
};
VIZI.BlueprintOutputImageTiles.prototype.createGrid = function(gridOptions) {
var self = this;
var gridOutput = {};
var grid = new VIZI.BlueprintHelperTileGrid(self.world, gridOptions);
grid.on("moved", function(tiles, diff) {
if (VIZI.DEBUG) console.log("Grid moved", tiles, diff);
// Wipe canvas
// TODO: This is pretty brutish and a better method for nice visuals (no snapping and wrong tiles) when moving should be found
gridOutput.context.clearRect(0, 0, gridOutput.canvas.width, gridOutput.canvas.height);
// Force an update so old tiles aren't shown briefly
gridOutput.mesh.material.needsUpdate = true;
gridOutput.mesh.material.map.needsUpdate = true;
// TODO: This whole tile size calculation probably only needs doing once
var geoBounds = {
ne: self.world.project(new VIZI.LatLon(grid.boundsLatLon.n, grid.boundsLatLon.e)),
sw: self.world.project(new VIZI.LatLon(grid.boundsLatLon.s, grid.boundsLatLon.w))
};
// TODO: Likewise
var size = [Math.abs(geoBounds.ne.x - geoBounds.sw.x), Math.abs(geoBounds.ne.y - geoBounds.sw.y)];
// TODO: Likewise
gridOutput.mesh.position.x += (size[0] / grid.tileCount.x) * diff.x;
gridOutput.mesh.position.z += (size[1] / grid.tileCount.y) * diff.y;
// Only emit update event if grid is enabled
if (!grid.disable) {
self.emit("gridUpdated", tiles);
}
});
grid.on("disabled", function() {
if (VIZI.DEBUG) console.log("Grid disabled");
gridOutput.mesh.visible = false;
});
grid.on("enabled", function() {
if (VIZI.DEBUG) console.log("Grid enabled");
self.emit("gridUpdated", grid.tiles);
gridOutput.mesh.visible = true;
});
var tiles = grid.init();
if (VIZI.DEBUG) console.log("Grid initialised", tiles);
// Create canvas and object
self.createGridObject(grid, gridOutput);
gridOutput.grid = grid;
return gridOutput;
};
// TODO: Process this within a Web Worker
// TODO: Work out how to get CRS and other bits passed into (or replicated within) the worker
// TODO: Immediately hide grid if beyond camera cull point
// What's the best way of getting camera radius to here? Singleton?
VIZI.BlueprintOutputImageTiles.prototype.createGridObject = function(grid, output) {
var self = this;
// Create grid canvas
var tileCanvas = document.createElement("canvas");
var canvasSize = grid.tileCount.x * 256;
// Scale canvas to next power of 2 (for mipmap)
var canvasSizePower2 = Math.pow(2, Math.ceil(Math.log(canvasSize) / Math.log(2)));
// Canvas size difference
var canvasSizeDiff = canvasSizePower2 / canvasSize;
tileCanvas.width = canvasSizePower2;
tileCanvas.height = canvasSizePower2;
if (VIZI.DEBUG) console.log(tileCanvas.width, tileCanvas.height);
var tileCanvasContext = tileCanvas.getContext("2d");
// Create grid meshes and apply empty canvas materials (until tiles come through)
var texture = new THREE.Texture(tileCanvas);
// texture.minFilter = texture.magFilter = THREE.LinearFilter;
// Silky smooth images when tilted
texture.magFilter = THREE.LinearFilter;
texture.minFilter = THREE.LinearMipMapLinearFilter;
// TODO: Set this to renderer.getMaxAnisotropy() / 4
texture.anisotropy = 4;
var materialType = self.options.materialType;
if (!materialType || typeof THREE[materialType] !== "function") {
materialType = "MeshLambertMaterial";
}
var materialOptions = _.clone(self.options.materialOptions);
materialOptions.map = texture;
var material = new THREE[materialType](materialOptions);
// Update material otherwise canvas shows up black
material.needsUpdate = true;
material.map.needsUpdate = true;
var geoBounds = {
ne: self.world.project(new VIZI.LatLon(grid.boundsLatLon.n, grid.boundsLatLon.e)),
sw: self.world.project(new VIZI.LatLon(grid.boundsLatLon.s, grid.boundsLatLon.w))
};
// Why is this tilesize so random?
// TODO: Work out if the tilesize not being a proper square for square-shaped bounding coordinates is a problem (eg. 4825.486315913922, 4825.486315915361)
var size = [Math.abs(geoBounds.ne.x - geoBounds.sw.x), Math.abs(geoBounds.ne.y - geoBounds.sw.y)];
var geom = new THREE.PlaneBufferGeometry(size[0], size[1], 1, 1);
var gridMesh = new THREE.Mesh(geom, material);
// Hacky method for forcing render depth / layers using tile zoom
gridMesh.renderDepth = grid.tileZoom * -1;
var centerPos = [geoBounds.sw.x + (size[0] / 2), geoBounds.sw.y - (size[1] / 2)];
gridMesh.position.x = centerPos[0];
gridMesh.position.z = centerPos[1];
// Flip to horizontal
gridMesh.rotation.x = -90 * Math.PI / 180;
// TODO: Move to new VIZI.Mediator event system
// self.publish("addToScene", gridMesh);
// TODO: Make sure coordinate space is right
self.add(gridMesh);
output.canvas = tileCanvas;
output.canvasSizeDiff = canvasSizeDiff;
output.context = tileCanvasContext;
output.mesh = gridMesh;
return output;
};
// {
// x: 262116,
// y: 174348,
// z: 19
// }
VIZI.BlueprintOutputImageTiles.prototype.outputImageTile = function(image, tile) {
var self = this;
// Find grid
var gridHash = self.grids[tile.z];
// Retreive grid canvas context
var context = gridHash.context;
// Sizing factor caused by power of 2 canvas dimensions
var canvasSizeDiff = gridHash.canvasSizeDiff;
var localCoords = gridHash.grid.globalToLocalTiles(tile.x, tile.y);
var imagePos = [(localCoords.x * 256) * canvasSizeDiff, (localCoords.y * 256) * canvasSizeDiff];
// Update canvas with tile
context.drawImage(image, imagePos[0], imagePos[1], 256 * canvasSizeDiff, 256 * canvasSizeDiff);
if (self.debug) {
context.strokeStyle = "#ff0000";
context.lineWidth = 5;
context.strokeRect(imagePos[0], imagePos[1], 256, 256);
}
gridHash.mesh.material.needsUpdate = true;
gridHash.mesh.material.map.needsUpdate = true;
// if (VIZI.DEBUG) console.log("Output tile", image, tile);
};
VIZI.BlueprintOutputImageTiles.prototype.onAdd = function(world) {
var self = this;
self.world = world;
self.init();
};
}());

Wyświetl plik

@ -0,0 +1,199 @@
/* globals window, _, VIZI */
(function() {
"use strict";
/**
* Blueprint switchboard
* @author Robin Hawkes - vizicities.com
*/
var arrayIndexRegEx = /\[(\d+)\]/,
arrayIndexRegExG = /\[(\d+)\]/g;
VIZI.BlueprintSwitchboard = function(config) {
var self = this;
if (!config) {
throw new Error("Required config argument missing");
}
self.input;
self.output;
self.processConfig(config);
};
// Process config into a working switchboard
VIZI.BlueprintSwitchboard.prototype.processConfig = function(config) {
var self = this;
if (!config.input) {
throw new Error("Required input configuration missing");
}
if (!config.output) {
throw new Error("Required output configuration missing");
}
if (!config.triggers) {
throw new Error("Required triggers configuration missing");
}
// Create input object (initialise after triggers are set)
self.input = self.createViziClassInstance(config.input.type, [config.input.options || {}]);
// Create output object (initialise after triggers are set)
self.output = self.createViziClassInstance(config.output.type, [config.output.options || {}]);
// Process triggers and actions
_.each(config.triggers, function(triggerOptions) {
if (triggerOptions.triggerObject !== "input" && triggerOptions.triggerObject !== "output") {
throw new Error("Trigger object should be either input or output");
}
var triggerObject = self[triggerOptions.triggerObject];
var triggerName = triggerOptions.triggerName;
var triggerArguments = triggerOptions.triggerArguments;
if (triggerOptions.actionObject !== "input" && triggerOptions.actionObject !== "output") {
throw new Error("Trigger object should be either input or output");
}
var actionObject = self[triggerOptions.actionObject];
var actionName = triggerOptions.actionName;
var actionArguments = triggerOptions.actionArguments;
var actionOutput = triggerOptions.actionOutput;
// Set up trigger listener
triggerObject.on(triggerName, function() {
if (VIZI.DEBUG) console.log("Trigger", triggerName, arguments);
var callbackArgs = arguments;
var actionArgs = [];
// Map trigger arguments to output arguments
_.each(actionArguments, function(actionArg, index) {
if (!actionOutput[actionArg]) {
throw new Error("Required action argument missing");
}
var triggerArg = actionOutput[actionArg];
// Simple 1:1 map of trigger argument to action argument
if (_.isString(triggerArg)) {
// if (VIZI.DEBUG) console.log("Trigger argument is a string", triggerArg);
actionArgs.push(callbackArgs[triggerArguments.indexOf(triggerArg)]);
// Advanced mapping of trigger argument to action argument
} else if (_.isObject(triggerArg)) {
if (VIZI.DEBUG) console.log("Trigger argument is an object", triggerArg);
var items = self.getValueByKeys(callbackArgs[triggerArguments.indexOf(triggerArg.itemsObject)], triggerArg.itemsProperties.split("."));
if (triggerArg.process === "map" && triggerArg.transformation) {
if (VIZI.DEBUG) console.log("Mapping trigger argument items using transformation", triggerArg.transformation);
items = (!_.isArray(items)) ? [items] : items;
var transformedItems = _.map(items, function(item) {
var output = {};
_.each(triggerArg.transformation, function(properties, key) {
if (_.isArray(properties)) {
output[key] = [];
_.each(properties, function(property) {
output[key].push(self.getValueByKeys(item, property.split(".")));
});
} else {
output[key] = self.getValueByKeys(item, properties.split("."));
}
});
return output;
});
actionArgs.push(transformedItems);
} else {
throw new Error("Required process or transformation option is missing");
}
}
});
// Call action with mapped arguments
if (VIZI.DEBUG) console.log("Action", actionName, actionArgs);
actionObject[actionName].apply(actionObject, actionArgs);
});
});
// TODO: Don't call init until addToWorld() is called
// TODO: Prevent possible race condition on initialisation triggers
// self.input.init();
// self.output.init();
};
// Create a dynamic VIZI class instance
// http://stackoverflow.com/a/5054940/997339
VIZI.BlueprintSwitchboard.prototype.createViziClassInstance = function(className, args) {
if (!className) {
throw new Error("Required class name missing");
}
if (!VIZI[className]) {
throw new Error("VIZI." + className + " class could not be found");
}
// http://stackoverflow.com/a/5054940/997339
var instance = VIZI[className];
var params = [instance].concat(args);
return new (instance.bind.apply(instance, params))();
};
// Split object string into real values
// Retreives the value for "exampleObj.property"
// Also retreives the value for "exampleObj.geometry[0]"
VIZI.BlueprintSwitchboard.prototype.getValueByKeys = function(object, keys) {
var output = object;
_.each(keys, function(key) {
if (!output) return null;
// Check for array reference in key
if (arrayIndexRegEx.test(key)) {
var arrayKey = key.split("[")[0];
var arrayIndex;
arrayIndexRegExG.lastIndex = 0;
while ((arrayIndex = arrayIndexRegExG.exec(key)) !== null) {
output = output[arrayKey][arrayIndex[1]];
}
// Else, assume key is not an array
} else {
output = output[key];
}
});
return output;
};
VIZI.BlueprintSwitchboard.prototype.addToWorld = function(world) {
var self = this;
if (VIZI.DEBUG) console.log("Adding Blueprint to world", self);
world.addSwitchboard(self);
self.input.init();
// Add output to world
self.output.addToWorld(world);
};
VIZI.BlueprintSwitchboard.prototype.onTick = function(delta) {
var self = this;
if (!self.output) return;
self.output.onTick(delta);
};
}());

Wyświetl plik

@ -0,0 +1,26 @@
/* globals window, _, VIZI */
/**
* Main control class
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Controls = function(camera, options) {
var self = this;
VIZI.EventEmitter.call(self);
self.options = options || {};
_.defaults(self.options, {});
if (!camera) {
throw new Error("Required camera missing");
}
};
VIZI.Controls.prototype = Object.create( VIZI.EventEmitter.prototype );
})();

Wyświetl plik

@ -0,0 +1,48 @@
/* globals window, _, VIZI, THREE */
/**
* First person control class
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.ControlsFirstPerson = function(camera, options) {
var self = this;
VIZI.Controls.call(self, camera, options);
self.controls = new THREE.FirstPersonControls(camera.camera, self.options.viewport.querySelector("canvas"));
self.controls.movementSpeed = 750;
self.controls.lookSpeed = 0.075;
self.controls.lookVertical = true;
// TODO: Handle window resize and update based on DOM element not window size
// self.controls.handleResize();
// TODO: Add move and zoom event handlers like the map and orbit control system
};
VIZI.ControlsFirstPerson.prototype = Object.create( VIZI.Controls.prototype );
VIZI.ControlsFirstPerson.prototype.moveTo = function(point) {
var self = this;
self.controls.object.x = point.x;
self.controls.object.z = point.y;
self.controls.update();
};
VIZI.ControlsFirstPerson.prototype.moveBy = function(delta) {
var self = this;
self.controls.object.x += delta.x;
self.controls.object.z += delta.y;
self.controls.update();
};
VIZI.ControlsFirstPerson.prototype.onTick = function(delta) {
var self = this;
self.controls.update(delta);
};
})();

Wyświetl plik

@ -0,0 +1,102 @@
/* globals window, _, VIZI, THREE */
/**
* Map control class
* https://github.com/mattzhao92/Planet-Blitz/blob/master/libs/MapControls.js
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.ControlsMap = function(camera, options) {
var self = this;
VIZI.Controls.call(self, camera, options);
self.controls = new THREE.MapControls(camera.camera, self.options.viewport.querySelector("canvas"));
self.controls.maxPolarAngle = 1.5533430342749535; // 89 degrees
self.controls.addEventListener("start", function(event) {
self.onStart();
});
self.controls.addEventListener("change", function(event) {
self.onChange();
});
self.controls.addEventListener("end", function(event) {
self.onEnd();
});
};
VIZI.ControlsMap.prototype = Object.create( VIZI.Controls.prototype );
VIZI.ControlsMap.prototype.onStart = function() {
var self = this;
};
// TODO: Send more refined events, perhaps capped per second to prevent spam
VIZI.ControlsMap.prototype.onChange = function() {
var self = this;
// TODO: Only emit this if it has changed
var point = new VIZI.Point(self.controls.target.x, self.controls.target.z);
VIZI.Messenger.emit("controls:move", point);
// TODO: Only emit this if it has changed
var zoom = self.getZoom();
VIZI.Messenger.emit("controls:zoom", zoom);
};
VIZI.ControlsMap.prototype.onEnd = function() {
var self = this;
};
VIZI.ControlsMap.prototype.moveTo = function(point) {
var self = this;
// TODO: Work out some cleaner way to map between Vector2 and Vector3
var diff = point.clone().sub(new VIZI.Point(self.controls.target.x, self.controls.target.z));
self.controls.panX(diff.x);
self.controls.panZ(diff.y);
self.controls.update();
};
VIZI.ControlsMap.prototype.moveBy = function(delta) {
var self = this;
self.controls.panX(delta.x);
self.controls.panZ(delta.y);
self.controls.update();
};
// Zoom to specified distance in pixels
VIZI.ControlsMap.prototype.zoomTo = function(distance) {
var self = this;
if (distance < 10) return;
var dollyScale = distance / self.controls.offset.length();
if (dollyScale > 0) {
self.controls.dollyOut(dollyScale);
} else if (dollyScale < 0) {
self.controls.dollyIn(dollyScale);
}
self.controls.update();
};
VIZI.ControlsMap.prototype.getZoom = function() {
var self = this;
return self.controls.offset.length();
};
VIZI.ControlsMap.prototype.onTick = function(delta) {
var self = this;
self.controls.update(delta);
};
})();

Wyświetl plik

@ -0,0 +1,157 @@
/* globals window, _, VIZI */
/**
* Mouse picking controls class
* @author Robin Hawkes - vizicities.com
*/
// TODO: Prevent click (and hover events?) from triggering while moving camera
(function() {
"use strict";
VIZI.ControlsMousePick = function(camera, options) {
var self = this;
VIZI.Controls.call(self, camera, options);
if (!self.options.scene) {
throw new Error("Required scene option missing");
}
self.camera = camera;
self.pixelBuffer = new Uint8Array(4);
self.lastPickedIdHover;
self.validClick = true;
self.options.scene.options.viewport.addEventListener("mousemove", self.onMouseMove.bind(self), false);
self.options.scene.options.viewport.addEventListener("mousedown", self.onMouseDown.bind(self), false);
self.options.scene.options.viewport.addEventListener("mouseup", self.onMouseUp.bind(self), false);
};
VIZI.ControlsMousePick.prototype = Object.create( VIZI.Controls.prototype );
// TODO: Is this called less on mousemove than it would be on each tick?
// If not, either move to each tick (and be called when not needed), or
// set a minimum amount of time to pass before re-picking on move (eg. 100ms)
// Could use _.trottle to cap to a certain threshold
VIZI.ControlsMousePick.prototype.onMouseMove = function(event) {
var self = this;
// Removed until proven necessary as it was interfering with layers UI
//event.preventDefault();
// Invalidate any clicks as the mouse has moved
self.validClick = false;
var screenPos = new VIZI.Point(event.clientX, event.clientY);
var viewportOffset = new VIZI.Point(
self.options.scene.options.viewport.offsetLeft,
self.options.scene.options.viewport.offsetTop
);
var relativePos = screenPos.clone().subtract(viewportOffset);
var ref = self.pick(relativePos);
if (!ref) {
if (self.lastPickedIdHover) {
// Emit event with picked id (for other modules to reference from)
VIZI.Messenger.emit("pick-off:" + self.lastPickedIdHover);
self.lastPickedIdHover = undefined;
}
return;
}
if (self.lastPickedIdHover && self.lastPickedIdHover === ref.id) {
return;
} else if (self.lastPickedIdHover && self.lastPickedIdHover !== ref.id) {
// Emit event with picked id (for other modules to reference from)
VIZI.Messenger.emit("pick-off:" + self.lastPickedIdHover);
}
// Emit event with picked id (for other modules to reference from)
VIZI.Messenger.emit("pick-hover:" + ref.id);
self.lastPickedIdHover = ref.id;
};
VIZI.ControlsMousePick.prototype.onMouseDown = function(event) {
var self = this;
// Skip if right button
if (event.button === 2) {
return;
}
self.validClick = true;
};
VIZI.ControlsMousePick.prototype.onMouseUp = function(event) {
var self = this;
// Skip if right button
if (event.button === 2) {
return;
}
// Skip if click has been invalidated by movement
if (!self.validClick) {
return;
}
// Removed until proven necessary as it was interfering with layers UI
//event.preventDefault();
var screenPos = new VIZI.Point(event.clientX, event.clientY);
var viewportOffset = new VIZI.Point(
self.options.scene.options.viewport.offsetLeft,
self.options.scene.options.viewport.offsetTop
);
var relativePos = screenPos.clone().subtract(viewportOffset);
var ref = self.pick(relativePos);
if (!ref) {
return;
}
// Emit event with picked id (for other modules to reference from)
VIZI.Messenger.emit("pick-click:" + ref.id);
};
// TODO: Fix issue where ID is being picked up even when clicking outside of objects within scene
VIZI.ControlsMousePick.prototype.pick = function(pos) {
var self = this;
if (!pos) {
console.log("No position given for picking");
return;
}
// Render picking scene
self.options.scene.renderPicking(self.camera);
// Get the gl buffer
var gl = self.options.scene.renderer.getContext();
// Read pixel under the mouse into buffer
gl.readPixels(pos.x, self.options.scene.pickingTexture.height - pos.y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, self.pixelBuffer);
// Get picked object
var id = (self.pixelBuffer[0] << 16) | (self.pixelBuffer[1] << 8) | (self.pixelBuffer[2]);
// Highlight picked object
// self.options.scene.highlightPickable(id);
var ref = self.options.scene.getPickable(id);
if (!ref) {
return;
}
return ref;
};
})();

Wyświetl plik

@ -0,0 +1,101 @@
/* globals window, _, VIZI, THREE */
/**
* Orbit control class
* https://github.com/mrdoob/three.js/blob/master/examples/misc_controls_orbit.html
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.ControlsOrbit = function(camera, options) {
var self = this;
VIZI.Controls.call(self, camera, options);
self.controls = new THREE.OrbitControls(camera.camera, self.options.viewport.querySelector("canvas"));
self.controls.addEventListener("start", function(event) {
self.onStart();
});
self.controls.addEventListener("change", function(event) {
self.onChange();
});
self.controls.addEventListener("end", function(event) {
self.onEnd();
});
};
VIZI.ControlsOrbit.prototype = Object.create( VIZI.Controls.prototype );
VIZI.ControlsOrbit.prototype.onStart = function() {
var self = this;
};
// TODO: Send more refined events, perhaps capped per second to prevent spam
VIZI.ControlsOrbit.prototype.onChange = function() {
var self = this;
// TODO: Only emit this if it has changed
var point = new VIZI.Point(self.controls.target.x, self.controls.target.z);
VIZI.Messenger.emit("controls:move", point);
// TODO: Only emit this if it has changed
var zoom = self.getZoom();
VIZI.Messenger.emit("controls:zoom", zoom);
};
VIZI.ControlsOrbit.prototype.onEnd = function() {
var self = this;
};
VIZI.ControlsOrbit.prototype.moveTo = function(point) {
var self = this;
// TODO: Work out some cleaner way to map between Vector2 and Vector3
var diff = point.clone().sub(new VIZI.Point(self.controls.target.x, self.controls.target.z));
self.controls.panX(diff.x);
self.controls.panZ(diff.y);
self.controls.update();
};
VIZI.ControlsOrbit.prototype.moveBy = function(delta) {
var self = this;
self.controls.panX(delta.x);
self.controls.panZ(delta.y);
self.controls.update();
};
// Zoom to specified distance in pixels
VIZI.ControlsOrbit.prototype.zoomTo = function(distance) {
var self = this;
if (distance < 10) return;
var dollyScale = distance / self.controls.offset.length();
if (dollyScale > 0) {
self.controls.dollyOut(dollyScale);
} else if (dollyScale < 0) {
self.controls.dollyIn(dollyScale);
}
self.controls.update();
};
VIZI.ControlsOrbit.prototype.getZoom = function() {
var self = this;
return self.controls.offset.length();
};
VIZI.ControlsOrbit.prototype.onTick = function(delta) {
var self = this;
self.controls.update(delta);
};
})();

Wyświetl plik

@ -0,0 +1,52 @@
/* globals window, _, VIZI */
/**
* Attribution UI
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Attribution = function(options) {
var self = this;
if (VIZI.DEBUG) console.log("Initialising VIZI.Attribution");
self.options = options || {};
_.defaults(self.options, {});
if (!self.options.element) {
throw new Error("Required element option missing");
}
self.defaultMessage = "<a href='http://vizicities.com' target='_blank'>Powered by ViziCities</a>";
self.container = self.createContainer(self.options.element);
self.add(self.defaultMessage);
};
VIZI.Attribution.prototype.createContainer = function(element) {
var container = document.createElement("div");
// Styling is adding via vizicities.css
container.classList.add("vizicities-attribution");
element.appendChild(container);
return container;
};
VIZI.Attribution.prototype.add = function(message) {
var self = this;
var prefix = "";
if (self.container.innerHTML.length > 0) {
prefix = " | ";
}
self.container.innerHTML += prefix + message;
};
})();

20
src/Core/Clock.js 100644
Wyświetl plik

@ -0,0 +1,20 @@
/* globals window, _, VIZI, THREE */
/**
* Clock
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Clock = function() {
if (VIZI.DEBUG) console.log("Initialising VIZI.Clock");
var self = this;
THREE.Clock.call(self);
};
VIZI.Clock.prototype = Object.create( THREE.Clock.prototype );
})();

Wyświetl plik

@ -0,0 +1,18 @@
/* globals window, _, VIZI, WildEmitter */
/**
* Event emitter
* Based on WildEmitter
* https://github.com/HenrikJoreteg/wildemitter
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.EventEmitter = function() {
WildEmitter.call(this);
};
VIZI.EventEmitter.prototype = Object.create( WildEmitter.prototype );
}());

Wyświetl plik

@ -0,0 +1,15 @@
/* globals window, VIZI */
/**
* System-wide event messenger
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Messenger = (function() {
var emitter = new VIZI.EventEmitter();
return emitter;
}());
}());

283
src/Core/World.js 100644
Wyświetl plik

@ -0,0 +1,283 @@
/* globals window, _, VIZI */
/**
* Main entry point
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.World = function(options) {
if (VIZI.DEBUG) console.log("Initialising VIZI.World");
var self = this;
self.options = options || {};
_.defaults(self.options, {
crs: VIZI.CRS.EPSG3857,
center: new VIZI.LatLon(51.50358, -0.01924),
zoom: 16,
suppressRenderer: false, // Set true for tests
layersUI: true,
picking: false,
antialias: false
});
if (!self.options.viewport) {
throw new Error("Required viewport option missing");
}
self.crs = self.options.crs;
self.attribution = new VIZI.Attribution({
element: self.options.viewport
});
// TODO: Store switchboards and layers in an id-referenced object
self.switchboards = [];
self.layers = [];
// Add UI container
// TODO: Move into a separate UI class
var uiContainer = document.createElement("div");
// Styling is adding via vizicities.css
uiContainer.classList.add("vizicities-ui");
self.options.viewport.appendChild(uiContainer);
// Set up layer UI
if (self.options.layersUI) {
self.layersUI = new VIZI.LayersUI(self.layers);
}
// TODO: Ability to override this with a scene passed into the options
// TODO: Pass-through options that tweak scene (antialias, etc)
self.scene = new VIZI.Scene({
antialias: self.options.antialias,
viewport: self.options.viewport,
// TODO: Remove this when running WebGL tests on Travis is solved
suppressRenderer: self.options.suppressRenderer,
picking: self.options.picking
});
self.camera = self.options.camera || new VIZI.Camera({
aspect: self.options.viewport.clientWidth / self.options.viewport.clientHeight
});
self.camera.addToScene(self.scene);
// Origins are used as a fixed base for position projections
self.origin = new VIZI.LatLon(self.options.center);
self.originZoom = self.options.zoom;
// Zoom and center are a dynamic representation of the current state
// These don't affect the values returned when projecting positions
self.zoom = undefined;
self.center = undefined;
self.updateView(self.options.center, self.options.zoom);
// Window resize
window.addEventListener("resize", function(event) {
self.resizeView(self.options.viewport.clientWidth, self.options.viewport.clientHeight);
});
VIZI.Messenger.on("controls:move", function(point) {
// TODO: Should be more intelligent about whether this has changed
var unprojected = self.unproject(point);
self.updateView(unprojected);
});
VIZI.Messenger.on("controls:zoom", function(distance) {
// Convert control zoom pixel distance to map zoom
// TODO: Work out a way to use meters instead of pixels (or not needed?)
var zoom = Math.ceil(self.crs.altitudeToZoom(distance));
// TODO: Should be more intelligent about whether this has changed
self.zoomTo(zoom);
});
};
VIZI.World.prototype.project = function(latLon, zoom) {
var self = this;
zoom = zoom || self.originZoom;
// TODO: Are there ramifications to rounding the pixels?
var originPoint = self.crs.latLonToPoint(self.origin, zoom, {round: false});
var projected = self.crs.latLonToPoint(latLon, zoom, {round: false});
return projected.clone().subtract(originPoint);
};
VIZI.World.prototype.unproject = function(point, zoom) {
var self = this;
zoom = zoom || self.originZoom;
// TODO: Are there ramifications to rounding the pixels?
var originPoint = self.crs.latLonToPoint(self.origin, zoom, {round: false});
return self.crs.pointToLatLon(point.clone().add(originPoint), zoom);
};
VIZI.World.prototype.pixelsPerMeter = function(latLon, zoom) {
var self = this;
zoom = zoom || self.originZoom;
return self.crs.pixelsPerMeter(latLon, zoom);
};
VIZI.World.prototype.addLayer = function(layer) {
var self = this;
self.layers.push(layer);
self.scene.add(layer.object);
// Update layers UI
if (self.layersUI) {
self.layersUI.onChange();
}
};
VIZI.World.prototype.addPickable = function(mesh, id) {
var self = this;
if (!self.options.picking) {
return;
}
self.scene.addPickable(mesh, id);
};
VIZI.World.prototype.addSwitchboard = function(switchboard) {
var self = this;
self.switchboards.push(switchboard);
};
// Update world and blueprint states on each frame
VIZI.World.prototype.onTick = function(delta) {
var self = this;
// REMOVED: As new NoFlo approach doesn't use switchboards
// _.each(self.switchboards, function(switchboard) {
// switchboard.onTick(delta);
// });
_.each(self.layers, function(layer) {
layer.onTick(delta);
});
};
// Render current world state
VIZI.World.prototype.render = function() {
var self = this;
self.scene.render(self.camera);
};
// Centralised method to handle variable changes and firing of events
// TODO: Trigger events as move and zoom progress
VIZI.World.prototype.updateView = function(center, zoom) {
var self = this;
if (zoom) {
self.zoom = zoom;
}
self.center = center;
// This will trigger things like a grid update within BlueprintOutput
VIZI.Messenger.emit("world:updateView", self.center, self.zoom);
};
VIZI.World.prototype.resizeView = function(width, height) {
var self = this;
var aspect = width / height;
self.camera.changeAspect(aspect);
self.scene.resize(width, height);
};
// REMOVED: These don't seem to be of any use in world
// It makes more sense to change camera movement via the controls
// These helpers would make more sense if a reference to controls was
// stored in the world class.
// VIZI.World.prototype.moveToLatLon = function(latLon) {
// var self = this;
// self.updateView(latLon);
// };
// VIZI.World.prototype.moveToPoint = function(point) {
// var self = this;
// // TODO: Are there ramifications to not rounding the pixels?
// var unprojected = self.unproject(point);
// self.updateView(unprojected);
// };
// VIZI.World.prototype.moveBy = function(point) {
// var self = this;
// // TODO: Are there ramifications to not rounding the pixels?
// var centerProjected = self.crs.latLonToPoint(self.center, self.zoom);
// var newPoint = centerProjected.clone().add(point);
// self.updateView(self.crs.pointToLatLon(newPoint, self.zoom));
// };
// TODO: Should this be handled within the controls?
// What purpose does it serve here if it's not changing the control zoom?
VIZI.World.prototype.zoomTo = function(zoom) {
var self = this;
self.updateView(self.center, zoom);
};
// TODO: Should this be handled within the controls?
// What purpose does it serve here if it's not changing the control zoom?
VIZI.World.prototype.zoomIn = function(delta) {
var self = this;
self.updateView(self.center, self.zoom + delta);
};
// TODO: Should this be handled within the controls?
// What purpose does it serve here if it's not changing the control zoom?
VIZI.World.prototype.zoomOut = function(delta) {
var self = this;
self.updateView(self.center, self.zoom - delta);
};
// TODO: Trigger events as camera change progresses
// TODO: Should this be handled within the controls?
// What purpose does it serve here?
VIZI.World.prototype.lookAtLatLon = function(latLon) {
var self = this;
var projected = self.project(latLon);
self.camera.lookAt(projected);
};
// TODO: Trigger events as camera change progresses
// TODO: Should this be handled within the controls?
// What purpose does it serve here?
VIZI.World.prototype.lookAtPoint = function(point) {
var self = this;
self.camera.lookAt(point);
};
// From: http://stackoverflow.com/a/27412386/997339
VIZI.World.prototype.worldPositionTo2D = function(position) {
var self = this;
var vector3 = position.clone();
// Map to normalized device coordinate (NDC) space
vector3.project(self.camera.camera);
// Map to 2D screen space
var position2D = new VIZI.Point();
position2D.x = Math.round((vector3.x + 1) * self.options.viewport.clientWidth / 2),
position2D.y = Math.round((-vector3.y + 1) * self.options.viewport.clientHeight / 2);
return position2D;
};
})();

Wyświetl plik

@ -0,0 +1,19 @@
/* globals window, _, VIZI, proj4 */
/**
* Spherical mercator CRS - EPSG:3857 (aka. EPSG:900913)
* More info: http://epsg.io/3857
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.CRS.EPSG3857 = _.extend({}, VIZI.CRS, {
code: "EPSG:3857"
});
VIZI.CRS.EPSG900913 = _.extend({}, VIZI.CRS.EPSG3857, {
code: "EPSG:900913"
});
}());

297
src/Geo/CRS.js 100644
Wyświetl plik

@ -0,0 +1,297 @@
/* globals window, _, VIZI, proj4 */
/**
* Coordinate reference system
* Inspired by Leaflet's CRS management
* CRS reference: http://epsg.io/
* Coordinate conversion from:
* http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
* http://stackoverflow.com/questions/12896139/geographic-coordinates-converter
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
var EARTH_DIAMETER = 2 * 6378137;
var EARTH_CIRCUMFERENCE = Math.PI * EARTH_DIAMETER;
var ORIGIN_SHIFT = EARTH_CIRCUMFERENCE / 2;
// TODO: Handle non-EPSG:3857 coordinate projection to and from pixels
// TODO: Create a method to get meters-to-pixels ratio for heights (like buildings) - resolution() doesn't seem to be right for this case
VIZI.CRS = {
code: undefined,
tileSize: 256,
projection: undefined,
inverseProjection: undefined,
// Project WGS84 coordinates into pixel positions
// TODO: Project non-EPSG:3857 CRS into EPSG:3857 for pixel coords
latLonToPoint: function(latLon, zoom, options) {
var self = this;
options = options || {};
_.defaults(options, {
convert: true,
round: false
});
var projected = self.project(latLon);
var resolution = self.resolution(zoom);
var point;
if (options.round === true) {
// TODO: Should rounding be performed? What ramifications does this have?
// - WebGL 'pixels' aren't quite the same as screen pixels so non-integers should be ok (and more accurate)
point = new VIZI.Point(
Math.round((projected[0] + ORIGIN_SHIFT) / resolution),
Math.round((projected[1] + ORIGIN_SHIFT) / resolution)
);
} else {
point = new VIZI.Point(
(projected[0] + ORIGIN_SHIFT) / resolution,
(projected[1] + ORIGIN_SHIFT) / resolution
);
}
if (options.convert !== false) {
// Convert point so origin is top-left not bottom-left
var mapSize = self.tileSize << zoom;
point.y = mapSize - point.y;
}
return point;
},
// Project pixel positions into WGS84 coordinates
// TODO: Project into EPSG:3857 coords before projecting into CRS
pointToLatLon: function(point, zoom) {
var self = this;
var resolution = self.resolution(zoom);
var mapSize = self.tileSize << zoom;
var crsPoint = new VIZI.Point(
point.x * resolution - ORIGIN_SHIFT,
// Convert point so origin is bottom-left not top-left
(mapSize - point.y) * resolution - ORIGIN_SHIFT
);
var unprojected = self.unproject(crsPoint);
return new VIZI.LatLon(unprojected[1], unprojected[0]);
},
// Google tile bounds in WGS84 coords
tileBoundsLatLon: function(tile, zoom) {
var self = this;
var min = self.pointToLatLon({x: tile.x * self.tileSize, y: tile.y * self.tileSize}, zoom);
var max = self.pointToLatLon({x: (tile.x+1) * self.tileSize, y: (tile.y+1) * self.tileSize}, zoom);
var bounds = {
n: min.lat,
e: max.lon,
s: max.lat,
w: min.lon
};
return bounds;
},
// Google tile bounds in pixel positions
tileBoundsPoint: function(tile, zoom) {
var self = this;
var min = self.pointToLatLon({x: tile.x * self.tileSize, y: tile.y * self.tileSize}, zoom);
var max = self.pointToLatLon({x: (tile.x+1) * self.tileSize, y: (tile.y+1) * self.tileSize}, zoom);
var projectedMin = self.latLonToPoint(min, zoom);
var projectedMax = self.latLonToPoint(max, zoom);
var bounds = {
n: Math.round(projectedMin.y),
e: Math.round(projectedMax.x),
s: Math.round(projectedMax.y),
w: Math.round(projectedMin.x)
};
return bounds;
},
// Convert pixel point to Google tile
// TODO: Convert to VIZI.Point
pointToTile: function(point) {
var self = this;
var tile = new VIZI.Point(
Math.ceil(point.x / self.tileSize) - 1,
Math.ceil(point.y / self.tileSize) - 1
);
return tile;
},
// Convert pixel point to TMS tile
// TODO: Convert to VIZI.Point
pointToTileTMS: function(point, zoom) {
var self = this;
var tile = self.pointToTile(point);
return self.convertTile(tile, zoom);
},
// Convert WGS84 coordinates to Google tile
latLonToTile: function(latLon, zoom) {
var self = this;
var point = self.latLonToPoint(latLon, zoom);
return self.pointToTile(point);
},
// Convert WGS84 coordinates to TMS tile
latLonToTileTMS: function(latLon, zoom) {
var self = this;
// Don't move point origin to top-left as we're using TMS
var point = self.latLonToPoint(latLon, zoom, {convert: false});
return self.pointToTile(point);
},
// Find WGS84 coordinates of Google tile center
tileToLatLon: function(tile, zoom) {
var self = this;
var bounds = self.tileBoundsLatLon(tile, zoom);
return new VIZI.LatLon(
bounds.s + (bounds.n - bounds.s) / 2,
bounds.w + (bounds.e - bounds.w) / 2
);
},
// Convert either way between TMS tile and Google tile
// TODO: Convert to VIZI.Point
convertTile: function(tile, zoom) {
return new VIZI.Point(tile.x, (Math.pow(2, zoom) - 1) - tile.y);
},
setProjection: function(code) {
var self = this;
if (code === undefined) {
code = self.code;
}
if (!self.projection || code !== self.code) {
self.projection = new proj4.Proj(self.code);
self.inverseProjection = proj4(self.projection).inverse;
}
},
// Convert WGS84 coordinates into CRS
project: function(latLon) {
var self = this;
self.setProjection();
return proj4(self.projection, [latLon.lon, latLon.lat]);
},
// Convert CRS into WGS84 coordinates
unproject: function(point) {
var self = this;
self.setProjection();
return self.inverseProjection([point.x, point.y]);
},
// Map resolution (meters per pixel) for a given zoom
resolution: function(zoom) {
var self = this;
return EARTH_CIRCUMFERENCE / (self.tileSize * Math.pow(2, zoom));
},
// Distance in meters between two WGS84 coordinates
// http://www.movable-type.co.uk/scripts/latlong.html
// http://stackoverflow.com/questions/4102520/how-to-transform-a-distance-from-degrees-to-metres
// http://jsperf.com/haversine-salvador/5
distance: function(latLon1, latLon2) {
var deg2rad = 0.017453292519943295; // === Math.PI / 180
var cos = Math.cos;
var lat1 = latLon1.lat * deg2rad;
var lon1 = latLon1.lon * deg2rad;
var lat2 = latLon2.lat * deg2rad;
var lon2 = latLon2.lon * deg2rad;
// var diam = 12742; // Diameter of the earth in km (2 * 6371)
var diam = EARTH_DIAMETER; // Diameter of the earth in meters
var dLat = lat2 - lat1;
var dLon = lon2 - lon1;
var a = (
(1 - cos(dLat)) +
(1 - cos(dLon)) * cos(lat1) * cos(lat2)
) / 2;
return diam * Math.asin(Math.sqrt(a));
},
// http://gis.stackexchange.com/questions/75528/length-of-a-degree-where-do-the-terms-in-this-formula-come-from
metersPerDegree: function(latLon) {
// Convert latitude to radians
var lat = latLon.lat * Math.PI / 180;
// Set up "Constants"
var m1 = 111132.92; // latitude calculation term 1
var m2 = -559.82; // latitude calculation term 2
var m3 = 1.175; // latitude calculation term 3
var m4 = -0.0023; // latitude calculation term 4
var p1 = 111412.84; // longitude calculation term 1
var p2 = -93.5; // longitude calculation term 2
var p3 = 0.118; // longitude calculation term 3
// Calculate the length of a degree of latitude and longitude in meters
var latLen = m1 + (m2 * Math.cos(2 * lat)) + (m3 * Math.cos(4 * lat)) + (m4 * Math.cos(6 * lat));
var lonLen = (p1 * Math.cos(lat)) + (p2 * Math.cos(3 * lat)) + (p3 * Math.cos(5 * lat));
return new VIZI.Point(Math.abs(lonLen), Math.abs(latLen));
},
pixelsPerDegree: function(latLon, zoom) {
var self = this;
// Find pixel position for latLon
var point1 = self.latLonToPoint(latLon, zoom);
// Find pixel position for latLon + 1
var point2 = self.latLonToPoint(new VIZI.LatLon(latLon.lat + 1, latLon.lon + 1), zoom);
// Find pixel length for a degree
return new VIZI.Point(Math.abs(point2.x - point1.x), Math.abs(point2.y - point1.y));
},
pixelsPerMeter: function(latLon, zoom) {
var self = this;
// Find meter length for a degree
var meters = self.metersPerDegree(latLon);
// Find pixel length for a degree
var pixels = self.pixelsPerDegree(latLon, zoom);
// Find ratio of pixels per meter at lonLat
return new VIZI.Point(pixels.x / meters.x, pixels.y / meters.y);
},
// These formulas are pretty hacky, though they'll probably do the job
// Altitude is in meters
altitudeToZoom: function(altitude) {
// https://gist.github.com/panzi/6694200
// var zoom = Math.floor(19 - Math.log(altitude / 1000) / Math.LN2);
// https://social.msdn.microsoft.com/Forums/en-US/5454d549-5eeb-43a5-b188-63121d3f0cc1/how-to-set-zoomlevel-for-particular-altitude?forum=bingmaps
// TODO: Use Math.log2 with a shim
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2#Polyfill
// var zoom = 19 - Math.log2(altitude * 0.05);
var zoom = 19 - (Math.log(altitude * 0.05) / Math.LN2);
// http://stackoverflow.com/a/13159839
// var scale = altitude / 500;
// var zoom = (19 - Math.log(scale) / Math.log(2));
return zoom < 0 ? 0 : zoom > 20 ? 20 : zoom;
}
};
}());

29
src/Geo/LatLon.js 100644
Wyświetl plik

@ -0,0 +1,29 @@
/* globals window, _, VIZI */
/**
* lat,lon,alt coordinates
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.LatLon = function(lat, lon, alt) {
var self = this;
self.lat = lat || 0;
self.lon = lon || 0;
self.alt = alt || 0; // Meters
// Copy if already a VIZI.LatLon instance
if (lat instanceof VIZI.LatLon) {
self.lat = lat.lat;
self.lon = lat.lon;
self.alt = lat.alt;
} else if (_.isArray(lat)) {
self.lat = lat[0];
self.lon = lat[1];
self.alt = lat[2] || 0;
}
};
})();

Wyświetl plik

@ -0,0 +1,46 @@
/* globals window, _, VIZI */
/**
* X,Y,Z coordinates
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Point = function(x, y, z) {
var self = this;
THREE.Vector3.call(self, x, y, z);
// TODO: Reimplement the following backups if needed
// self.x = x || 0;
// self.y = y || 0;
// self.z = z || 0;
// // Copy if already a VIZI.Point instance
// if (x instanceof VIZI.Point) {
// self.x = x.x;
// self.y = x.y;
// self.z = x.z;
// } else if (_.isArray(x)) {
// self.x = x[0];
// self.y = x[1];
// self.z = x[2] || 0;
// }
};
VIZI.Point.prototype = Object.create( THREE.Vector3.prototype );
// Override clone so it returns VIZI.Point not THREE.Vector3
VIZI.Point.prototype.clone = function(point) {
var self = this;
return new VIZI.Point(self.x, self.y, self.z);
};
// Proxy of sub
VIZI.Point.prototype.subtract = function(point) {
var self = this;
return self.sub(point);
};
})();

Wyświetl plik

@ -0,0 +1,67 @@
/* globals window, _, React, VIZI */
/**
* Description UI class
* @author Robin Hawkes - vizicities.com
*/
// TODO: Sort out scoping issues
// TODO: Work out a neater structure for defining the render method
(function() {
"use strict";
VIZI.DescriptionUI = function(options) {
var self = this;
var scope = self;
self.options = options || {};
_.defaults(options, {});
self.closed = false;
// Check that UI container exists
if (!document.querySelector(".vizicities-ui .vizicities-description-ui")) {
var container = document.createElement("section");
container.classList.add("vizicities-description-ui");
document.querySelector(".vizicities-ui").appendChild(container);
}
self.description = React.createClass({
render: function() {
var self = this;
var className = "vizicities-ui-item vizicities-description-ui-item";
className += (scope.closed) ? " closed" : "";
return (
<section className={className}>
<header onClick={self.props.onToggleClosed.bind(scope)}>
<h2>{self.props.title}</h2>
</header>
<p>{self.props.body}</p>
</section>
);
}
});
self.onChange();
};
VIZI.DescriptionUI.prototype.onToggleClosed = function() {
var self = this;
self.closed = (self.closed) ? false : true;
self.onChange();
};
VIZI.DescriptionUI.prototype.onChange = function() {
var self = this;
var Description = self.description;
React.render(<Description title={self.options.title} body={self.options.body} onToggleClosed={self.onToggleClosed} />, document.querySelector(".vizicities-description-ui"));
};
})();

114
src/UI/InfoUI2D.jsx 100644
Wyświetl plik

@ -0,0 +1,114 @@
/* globals window, _, React, VIZI */
/**
* 2D info UI class
* @author Robin Hawkes - vizicities.com
*/
// TODO: Sort out scoping issues
// TODO: Work out a neater structure for defining the render method
(function() {
"use strict";
VIZI.InfoUI2D = function(world) {
var self = this;
var scope = self;
self.world = world;
// Check that 2D info UI container exists
if (!document.querySelector(".vizicities-ui .vizicities-info-ui-2d")) {
var infoUIContainer = document.createElement("section");
infoUIContainer.classList.add("vizicities-info-ui-2d");
document.querySelector(".vizicities-ui").appendChild(infoUIContainer);
}
self.panels = {};
self.hidden = false;
self.infoUI = React.createClass({
render: function() {
var self = this;
var panels = _.map(self.props.panels, function(panel) {
var bounds = new THREE.Box3().setFromObject(panel.object);
var offsetPos = panel.object.position.clone();
offsetPos.y = bounds.max.y;
var screenPos = scope.world.worldPositionTo2D(offsetPos);
// TODO: Scale margin-top offset based on camera zoom so panel stays above the object
// TODO: Or, base the screen position on the top of the object bounding box
// TODO: Set z-index based on object distance from camera
var style = {
transform: "translateX(calc(" + screenPos.x + "px - 50%)) translateY(calc(" + screenPos.y + "px - 50%))",
display: (scope.hidden) ? "none" : "block"
}
return (
<div key={panel.id} style={style} className="vizicities-info-ui-2d-layer-item">{panel.text}</div>
);
});
return (
<section className="vizicities-info-ui-2d-layer">
{panels}
</section>
);
}
});
self.onChange();
};
VIZI.InfoUI2D.prototype.addPanel = function(object, text) {
var self = this;
var panel = {
id: object.id,
object: object,
text: text
};
self.panels[object.id] = panel;
self.onChange();
return panel;
};
VIZI.InfoUI2D.prototype.removePanel = function(id) {
var self = this;
if (!self.panels[id]) {
return;
}
delete self.panels[id];
self.onChange();
};
VIZI.InfoUI2D.prototype.onHide = function() {
var self = this;
self.hidden = true;
self.onChange();
};
VIZI.InfoUI2D.prototype.onShow = function() {
var self = this;
self.hidden = false;
self.onChange();
};
VIZI.InfoUI2D.prototype.onChange = function() {
var self = this;
var InfoUI = self.infoUI;
React.render(<InfoUI panels={self.panels} />, document.querySelector(".vizicities-info-ui-2d"));
};
})();

Wyświetl plik

@ -0,0 +1,103 @@
/* globals window, _, React, VIZI */
/**
* Key colour-scale UI class
* @author Robin Hawkes - vizicities.com
*/
// TODO: Sort out scoping issues
// TODO: Work out a neater structure for defining the render method
(function() {
"use strict";
VIZI.KeyUIColourScale = function(layer, scale) {
var self = this;
var scope = self;
self.layer = layer;
self.scale = scale || [];
self.description = layer.description || "";
self.hidden = false;
self.closed = false;
// Check that key UI container exists
if (!document.querySelector(".vizicities-ui .vizicities-key-ui")) {
var keyUIContainer = document.createElement("section");
keyUIContainer.classList.add("vizicities-key-ui");
document.querySelector(".vizicities-ui").appendChild(keyUIContainer);
}
self.key = React.createClass({
render: function() {
var self = this;
var scale = self.props.scale.map(function(scale) {
var style = {
background: scale.colour
};
return (
<li key={scale.colour}>
<span className="scale-icon" style={style}></span> {scale.key}
</li>
);
});
var className = "vizicities-ui-item vizicities-key-ui-item";
className += (scope.closed) ? " closed" : "";
var containerStyle = {
display: (scope.hidden) ? "none" : "block"
}
var description;
if (self.props.description) {
description = <li className="description">{self.props.description}</li>;
}
return (
<section className={className} style={containerStyle}>
<header onClick={self.props.onToggleClosed.bind(scope)}>
<h2>{scope.layer.name} key</h2>
</header>
<ul>
{description}
{scale}
</ul>
</section>
);
}
});
self.onChange();
};
VIZI.KeyUIColourScale.prototype.onHide = function() {
var self = this;
self.hidden = true;
self.onChange();
};
VIZI.KeyUIColourScale.prototype.onShow = function() {
var self = this;
self.hidden = false;
self.onChange();
};
VIZI.KeyUIColourScale.prototype.onToggleClosed = function() {
var self = this;
self.closed = (self.closed) ? false : true;
self.onChange();
};
VIZI.KeyUIColourScale.prototype.onChange = function() {
var self = this;
var Key = self.key;
React.render(<Key scale={self.scale} description={self.description} onToggleClosed={self.onToggleClosed} />, document.querySelector(".vizicities-key-ui"));
};
})();

110
src/UI/LayersUI.jsx 100644
Wyświetl plik

@ -0,0 +1,110 @@
/* globals window, _, React, VIZI */
/**
* Layers UI class
* @author Robin Hawkes - vizicities.com
*/
// TODO: Sort out scoping issues
// TODO: Work out a neater structure for defining the render method
(function() {
"use strict";
VIZI.LayersUI = function(layers) {
var self = this;
var scope = self;
self.layers = layers;
self.closed = true;
// Check that UI container exists
if (!document.querySelector(".vizicities-ui .vizicities-layers-ui")) {
var container = document.createElement("section");
container.classList.add("vizicities-layers-ui");
document.querySelector(".vizicities-ui").appendChild(container);
}
self.layerControl = React.createClass({
render: function() {
var self = this;
// TODO: De-dupe checkbox setup
var layers = self.props.layers.map(function(layer) {
var visibilityButton;
if (layer.hidden) {
visibilityButton = <input type="checkbox" onClick={self.props.onShow.bind(scope, layer.object.id)}></input>
} else {
visibilityButton = <input type="checkbox" checked onClick={self.props.onHide.bind(scope, layer.object.id)}></input>
}
return (
<li key={layer.object.id}>
{visibilityButton} {layer.name}
</li>
);
});
var className = "vizicities-ui-item vizicities-layers-ui-item";
className += (scope.closed) ? " closed" : "";
return (
<section className={className}>
<header onClick={self.props.onToggleClosed.bind(scope)}>
<h2>Layers</h2>
</header>
<ul>
{layers}
</ul>
</section>
);
}
});
self.onChange();
};
VIZI.LayersUI.prototype.onHideLayer = function(id) {
var self = this;
var layer = _.find(self.layers, function (layer) {
return layer.object.id === id;
});
if (layer) {
layer.hide();
}
self.onChange();
};
VIZI.LayersUI.prototype.onShowLayer = function(id) {
var self = this;
var layer = _.find(self.layers, function (layer) {
return layer.object.id === id;
});
if (layer) {
layer.show();
}
self.onChange();
};
VIZI.LayersUI.prototype.onToggleClosed = function() {
var self = this;
self.closed = (self.closed) ? false : true;
self.onChange();
};
VIZI.LayersUI.prototype.onChange = function() {
var self = this;
var LayerControl = self.layerControl;
React.render(<LayerControl layers={self.layers} onHide={self.onHideLayer} onShow={self.onShowLayer} onToggleClosed={self.onToggleClosed} />, document.querySelector(".vizicities-layers-ui"));
};
})();

5493
src/Vendor/ColladaLoader.js vendored 100644

Plik diff jest za duży Load Diff

278
src/Vendor/FirstPersonControls.js vendored 100644
Wyświetl plik

@ -0,0 +1,278 @@
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author paulirish / http://paulirish.com/
*/
THREE.FirstPersonControls = function ( object, domElement ) {
this.object = object;
this.target = new THREE.Vector3( 0, 0, 0 );
this.domElement = ( domElement !== undefined ) ? domElement : document;
this.enabled = true;
this.movementSpeed = 1.0;
this.lookSpeed = 0.005;
this.lookVertical = true;
this.autoForward = false;
this.activeLook = true;
this.heightSpeed = false;
this.heightCoef = 1.0;
this.heightMin = 0.0;
this.heightMax = 1.0;
this.constrainVertical = false;
this.verticalMin = 0;
this.verticalMax = Math.PI;
this.autoSpeedFactor = 0.0;
this.mouseX = 0;
this.mouseY = 0;
this.lat = 0;
this.lon = 0;
this.phi = 0;
this.theta = 0;
this.moveForward = false;
this.moveBackward = false;
this.moveLeft = false;
this.moveRight = false;
this.mouseDragOn = false;
this.viewHalfX = 0;
this.viewHalfY = 0;
if ( this.domElement !== document ) {
this.domElement.setAttribute( 'tabindex', -1 );
}
//
this.handleResize = function () {
if ( this.domElement === document ) {
this.viewHalfX = window.innerWidth / 2;
this.viewHalfY = window.innerHeight / 2;
} else {
this.viewHalfX = this.domElement.offsetWidth / 2;
this.viewHalfY = this.domElement.offsetHeight / 2;
}
};
this.onMouseDown = function ( event ) {
if ( this.domElement !== document ) {
this.domElement.focus();
}
event.preventDefault();
event.stopPropagation();
if ( this.activeLook ) {
switch ( event.button ) {
case 0: this.moveForward = true; break;
case 2: this.moveBackward = true; break;
}
}
this.mouseDragOn = true;
};
this.onMouseUp = function ( event ) {
event.preventDefault();
event.stopPropagation();
if ( this.activeLook ) {
switch ( event.button ) {
case 0: this.moveForward = false; break;
case 2: this.moveBackward = false; break;
}
}
this.mouseDragOn = false;
};
this.onMouseMove = function ( event ) {
if ( this.domElement === document ) {
this.mouseX = event.pageX - this.viewHalfX;
this.mouseY = event.pageY - this.viewHalfY;
} else {
this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
}
};
this.onKeyDown = function ( event ) {
//event.preventDefault();
switch ( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ this.moveForward = true; break;
case 37: /*left*/
case 65: /*A*/ this.moveLeft = true; break;
case 40: /*down*/
case 83: /*S*/ this.moveBackward = true; break;
case 39: /*right*/
case 68: /*D*/ this.moveRight = true; break;
case 82: /*R*/ this.moveUp = true; break;
case 70: /*F*/ this.moveDown = true; break;
}
};
this.onKeyUp = function ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ this.moveForward = false; break;
case 37: /*left*/
case 65: /*A*/ this.moveLeft = false; break;
case 40: /*down*/
case 83: /*S*/ this.moveBackward = false; break;
case 39: /*right*/
case 68: /*D*/ this.moveRight = false; break;
case 82: /*R*/ this.moveUp = false; break;
case 70: /*F*/ this.moveDown = false; break;
}
};
this.update = function( delta ) {
if ( this.enabled === false ) return;
if ( this.heightSpeed ) {
var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
var heightDelta = y - this.heightMin;
this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
} else {
this.autoSpeedFactor = 0.0;
}
var actualMoveSpeed = delta * this.movementSpeed;
if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );
if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
if ( this.moveRight ) this.object.translateX( actualMoveSpeed );
if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
var actualLookSpeed = delta * this.lookSpeed;
if ( !this.activeLook ) {
actualLookSpeed = 0;
}
var verticalLookRatio = 1;
if ( this.constrainVertical ) {
verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
}
this.lon += this.mouseX * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = THREE.Math.degToRad( 90 - this.lat );
this.theta = THREE.Math.degToRad( this.lon );
if ( this.constrainVertical ) {
this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );
}
var targetPosition = this.target,
position = this.object.position;
targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
targetPosition.y = position.y + 100 * Math.cos( this.phi );
targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
this.object.lookAt( targetPosition );
};
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
window.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
window.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
function bind( scope, fn ) {
return function () {
fn.apply( scope, arguments );
};
};
this.handleResize();
};

544
src/Vendor/JSONLoader.js vendored 100644
Wyświetl plik

@ -0,0 +1,544 @@
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
THREE.JSONLoader = function ( showStatus ) {
THREE.Loader.call( this, showStatus );
this.withCredentials = false;
};
THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
var scope = this;
// todo: unify load API to for easier SceneLoader use
texturePath = texturePath && ( typeof texturePath === 'string' ) ? texturePath : this.extractUrlBase( url );
this.onLoadStart();
this.loadAjaxJSON( this, url, callback, texturePath );
};
THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
var xhr = new XMLHttpRequest();
var length = 0;
xhr.onreadystatechange = function () {
if ( xhr.readyState === xhr.DONE ) {
if ( xhr.status === 200 || xhr.status === 0 ) {
if ( xhr.responseText ) {
var json = JSON.parse( xhr.responseText );
if ( json.metadata !== undefined && json.metadata.type === 'scene' ) {
console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' );
return;
}
var result = context.parse( json, texturePath );
callback( result.geometry, result.materials );
} else {
console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' );
}
// in context of more complex asset initialization
// do not block on single failed file
// maybe should go even one more level up
context.onLoadComplete();
} else {
console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' );
}
} else if ( xhr.readyState === xhr.LOADING ) {
if ( callbackProgress ) {
if ( length === 0 ) {
length = xhr.getResponseHeader( 'Content-Length' );
}
callbackProgress( { total: length, loaded: xhr.responseText.length } );
}
} else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
if ( callbackProgress !== undefined ) {
length = xhr.getResponseHeader( 'Content-Length' );
}
}
};
xhr.open( 'GET', url, true );
xhr.withCredentials = this.withCredentials;
xhr.send( null );
};
THREE.JSONLoader.prototype.parse = function ( json, texturePath ) {
var scope = this,
geometry = new THREE.Geometry(),
scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
parseModel( scale );
parseSkin();
parseMorphing( scale );
geometry.computeFaceNormals();
geometry.computeBoundingSphere();
function parseModel( scale ) {
function isBitSet( value, position ) {
return value & ( 1 << position );
}
var i, j, fi,
offset, zLength,
colorIndex, normalIndex, uvIndex, materialIndex,
type,
isQuad,
hasMaterial,
hasFaceVertexUv,
hasFaceNormal, hasFaceVertexNormal,
hasFaceColor, hasFaceVertexColor,
vertex, face, faceA, faceB, color, hex, normal,
uvLayer, uv, u, v,
faces = json.faces,
vertices = json.vertices,
normals = json.normals,
colors = json.colors,
nUvLayers = 0;
if ( json.uvs !== undefined ) {
// disregard empty arrays
for ( i = 0; i < json.uvs.length; i ++ ) {
if ( json.uvs[ i ].length ) nUvLayers ++;
}
for ( i = 0; i < nUvLayers; i ++ ) {
geometry.faceVertexUvs[ i ] = [];
}
}
offset = 0;
zLength = vertices.length;
while ( offset < zLength ) {
vertex = new THREE.Vector3();
vertex.x = vertices[ offset ++ ] * scale;
vertex.y = vertices[ offset ++ ] * scale;
vertex.z = vertices[ offset ++ ] * scale;
geometry.vertices.push( vertex );
}
offset = 0;
zLength = faces.length;
while ( offset < zLength ) {
type = faces[ offset ++ ];
isQuad = isBitSet( type, 0 );
hasMaterial = isBitSet( type, 1 );
hasFaceVertexUv = isBitSet( type, 3 );
hasFaceNormal = isBitSet( type, 4 );
hasFaceVertexNormal = isBitSet( type, 5 );
hasFaceColor = isBitSet( type, 6 );
hasFaceVertexColor = isBitSet( type, 7 );
// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
if ( isQuad ) {
faceA = new THREE.Face3();
faceA.a = faces[ offset ];
faceA.b = faces[ offset + 1 ];
faceA.c = faces[ offset + 3 ];
faceB = new THREE.Face3();
faceB.a = faces[ offset + 1 ];
faceB.b = faces[ offset + 2 ];
faceB.c = faces[ offset + 3 ];
offset += 4;
if ( hasMaterial ) {
materialIndex = faces[ offset ++ ];
faceA.materialIndex = materialIndex;
faceB.materialIndex = materialIndex;
}
// to get face <=> uv index correspondence
fi = geometry.faces.length;
if ( hasFaceVertexUv ) {
for ( i = 0; i < nUvLayers; i ++ ) {
uvLayer = json.uvs[ i ];
geometry.faceVertexUvs[ i ][ fi ] = [];
geometry.faceVertexUvs[ i ][ fi + 1 ] = []
for ( j = 0; j < 4; j ++ ) {
uvIndex = faces[ offset ++ ];
u = uvLayer[ uvIndex * 2 ];
v = uvLayer[ uvIndex * 2 + 1 ];
uv = new THREE.Vector2( u, v );
if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
}
}
}
if ( hasFaceNormal ) {
normalIndex = faces[ offset ++ ] * 3;
faceA.normal.set(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
faceB.normal.copy( faceA.normal );
}
if ( hasFaceVertexNormal ) {
for ( i = 0; i < 4; i ++ ) {
normalIndex = faces[ offset ++ ] * 3;
normal = new THREE.Vector3(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
if ( i !== 2 ) faceA.vertexNormals.push( normal );
if ( i !== 0 ) faceB.vertexNormals.push( normal );
}
}
if ( hasFaceColor ) {
colorIndex = faces[ offset ++ ];
hex = colors[ colorIndex ];
faceA.color.setHex( hex );
faceB.color.setHex( hex );
}
if ( hasFaceVertexColor ) {
for ( i = 0; i < 4; i ++ ) {
colorIndex = faces[ offset ++ ];
hex = colors[ colorIndex ];
if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );
}
}
geometry.faces.push( faceA );
geometry.faces.push( faceB );
} else {
face = new THREE.Face3();
face.a = faces[ offset ++ ];
face.b = faces[ offset ++ ];
face.c = faces[ offset ++ ];
if ( hasMaterial ) {
materialIndex = faces[ offset ++ ];
face.materialIndex = materialIndex;
}
// to get face <=> uv index correspondence
fi = geometry.faces.length;
if ( hasFaceVertexUv ) {
for ( i = 0; i < nUvLayers; i ++ ) {
uvLayer = json.uvs[ i ];
geometry.faceVertexUvs[ i ][ fi ] = [];
for ( j = 0; j < 3; j ++ ) {
uvIndex = faces[ offset ++ ];
u = uvLayer[ uvIndex * 2 ];
v = uvLayer[ uvIndex * 2 + 1 ];
uv = new THREE.Vector2( u, v );
geometry.faceVertexUvs[ i ][ fi ].push( uv );
}
}
}
if ( hasFaceNormal ) {
normalIndex = faces[ offset ++ ] * 3;
face.normal.set(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
}
if ( hasFaceVertexNormal ) {
for ( i = 0; i < 3; i ++ ) {
normalIndex = faces[ offset ++ ] * 3;
normal = new THREE.Vector3(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
face.vertexNormals.push( normal );
}
}
if ( hasFaceColor ) {
colorIndex = faces[ offset ++ ];
face.color.setHex( colors[ colorIndex ] );
}
if ( hasFaceVertexColor ) {
for ( i = 0; i < 3; i ++ ) {
colorIndex = faces[ offset ++ ];
face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
}
}
geometry.faces.push( face );
}
}
};
function parseSkin() {
var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
if ( json.skinWeights ) {
for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
var x = json.skinWeights[ i ];
var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
}
}
if ( json.skinIndices ) {
for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
var a = json.skinIndices[ i ];
var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
}
}
geometry.bones = json.bones;
if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
}
// could change this to json.animations[0] or remove completely
geometry.animation = json.animation;
geometry.animations = json.animations;
};
function parseMorphing( scale ) {
if ( json.morphTargets !== undefined ) {
var i, l, v, vl, dstVertices, srcVertices;
for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
geometry.morphTargets[ i ] = {};
geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
geometry.morphTargets[ i ].vertices = [];
dstVertices = geometry.morphTargets[ i ].vertices;
srcVertices = json.morphTargets [ i ].vertices;
for ( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
var vertex = new THREE.Vector3();
vertex.x = srcVertices[ v ] * scale;
vertex.y = srcVertices[ v + 1 ] * scale;
vertex.z = srcVertices[ v + 2 ] * scale;
dstVertices.push( vertex );
}
}
}
if ( json.morphColors !== undefined ) {
var i, l, c, cl, dstColors, srcColors, color;
for ( i = 0, l = json.morphColors.length; i < l; i ++ ) {
geometry.morphColors[ i ] = {};
geometry.morphColors[ i ].name = json.morphColors[ i ].name;
geometry.morphColors[ i ].colors = [];
dstColors = geometry.morphColors[ i ].colors;
srcColors = json.morphColors [ i ].colors;
for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
color = new THREE.Color( 0xffaa00 );
color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
dstColors.push( color );
}
}
}
};
if ( json.materials === undefined || json.materials.length === 0 ) {
return { geometry: geometry };
} else {
var materials = this.initMaterials( json.materials, texturePath );
if ( this.needsTangents( materials ) ) {
geometry.computeTangents();
}
return { geometry: geometry, materials: materials };
}
};

159
src/Vendor/JXON.js vendored 100644
Wyświetl plik

@ -0,0 +1,159 @@
/*
* JXON framework - Copyleft 2011 by Mozilla Developer Network
*
* https://developer.mozilla.org/en-US/docs/JXON
*
* This framework is released under the GNU Public License, version 3 or later.
* http://www.gnu.org/licenses/gpl-3.0-standalone.html
*
* small modifications performed by the iD project:
* https://github.com/openstreetmap/iD/commits/18aa33ba97b52cacf454e95c65d154000e052a1f/js/lib/jxon.js
*
* adapted for nodejs and npm by Martin Raifer <tyr.asd@gmail.com>
*/
if (typeof XMLSerializer === 'undefined') {
XMLSerializer = require("xmldom").XMLSerializer;
document = {};
document.implementation = new (require("xmldom").DOMImplementation)();
}
var JXON = new (function () {
var
sValueProp = "keyValue", sAttributesProp = "keyAttributes", sAttrPref = "@", /* you can customize these values */
aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
function parseText (sValue) {
if (rIsNull.test(sValue)) { return null; }
if (rIsBool.test(sValue)) { return sValue.toLowerCase() === "true"; }
if (isFinite(sValue)) { return parseFloat(sValue); }
if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
return sValue;
}
function EmptyTree () { }
EmptyTree.prototype.toString = function () { return "null"; };
EmptyTree.prototype.valueOf = function () { return null; };
function objectify (vValue) {
return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
}
function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
var
nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
var
sProp, vContent, nLength = 0, sCollectedTxt = "",
vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
if (bChildren) {
for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
oNode = oParentNode.childNodes.item(nItem);
if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */
else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */
// Removed "&& !oNode.prefix" as per namespace note on MDN
// https://developer.mozilla.org/en-US/docs/JXON
// else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is "Element" (1) */
else if (oNode.nodeType === 1) { aCache.push(oNode); } /* nodeType is "Element" (1) */
}
}
var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
sProp = aCache[nElId].nodeName.toLowerCase();
vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
if (vResult.hasOwnProperty(sProp)) {
if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
vResult[sProp].push(vContent);
} else {
vResult[sProp] = vContent;
nLength++;
}
}
if (bAttributes) {
var
nAttrLen = oParentNode.attributes.length,
sAPrefix = bNesteAttr ? "" : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
oAttrib = oParentNode.attributes.item(nAttrib);
oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
}
if (bNesteAttr) {
if (bFreeze) { Object.freeze(oAttrParent); }
vResult[sAttributesProp] = oAttrParent;
nLength -= nAttrLen - 1;
}
}
if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
vResult[sValueProp] = vBuiltVal;
} else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
vResult = vBuiltVal;
}
if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
aCache.length = nLevelStart;
return vResult;
}
function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
var vValue, oChild;
if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
} else if (oParentObj.constructor === Date) {
oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
}
for (var sName in oParentObj) {
vValue = oParentObj[sName];
if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
if (sName === sValueProp) {
if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
} else if (sName === sAttributesProp) { /* verbosity level is 3 */
for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
} else if (sName.charAt(0) === sAttrPref) {
oParentEl.setAttribute(sName.slice(1), vValue);
} else if (vValue.constructor === Array) {
for (var nItem = 0; nItem < vValue.length; nItem++) {
oChild = oXMLDoc.createElement(sName);
loadObjTree(oXMLDoc, oChild, vValue[nItem]);
oParentEl.appendChild(oChild);
}
} else {
oChild = oXMLDoc.createElement(sName);
if (vValue instanceof Object) {
loadObjTree(oXMLDoc, oChild, vValue);
} else if (vValue !== null && vValue !== true) {
oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
}
oParentEl.appendChild(oChild);
}
}
}
this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
};
this.unbuild = function (oObjTree) {
var oNewDoc = document.implementation.createDocument("", "", null);
loadObjTree(oNewDoc, oNewDoc, oObjTree);
return oNewDoc;
};
this.stringify = function (oObjTree) {
return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
};
})();

702
src/Vendor/MapControls.js vendored 100644
Wyświetl plik

@ -0,0 +1,702 @@
/**
* @author Robin Hawkes - vizicities.com
* @author qiao / https://github.com/qiao
* @author mrdoob / http://mrdoob.com
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
* @author erich666 / http://erichaines.com
*/
/*global THREE, console */
// This set of controls performs orbiting, dollying (zooming), and panning. It maintains
// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is
// supported.
//
// Orbit - left mouse / touch: one finger move
// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
// Pan - right mouse, or arrow keys / touch: three finter swipe
//
// This is a drop-in replacement for (most) TrackballControls used in examples.
// That is, include this js file and wherever you see:
// controls = new THREE.TrackballControls( camera );
// controls.target.z = 150;
// Simple substitute "OrbitControls" and the control should work as-is.
// TODO: Implement 1:1 movement between mouse position and target (raycasting)
// - http://stackoverflow.com/a/26187860/997339
THREE.MapControls = function ( object, domElement ) {
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
// API
// Set to false to disable this control
this.enabled = true;
// "target" sets the location of focus, where the control orbits around
// and where it pans with respect to.
this.target = new THREE.Vector3();
// center is old, deprecated; use "target" instead
this.center = this.target;
// This option actually enables dollying in and out; left as "zoom" for
// backwards compatibility
this.noZoom = false;
this.zoomSpeed = 1.0;
// Limits to how far you can dolly in and out
this.minDistance = 0;
this.maxDistance = Infinity;
// Set to true to disable this control
this.noRotate = false;
this.rotateSpeed = 1.0;
// Set to true to disable this control
this.noPan = false;
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
// Set to true to automatically rotate around the target
this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
// How far you can orbit vertically, upper and lower limits.
// Range is 0 to Math.PI radians.
this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians
// How far you can orbit horizontally, upper and lower limits.
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
this.minAzimuthAngle = - Infinity; // radians
this.maxAzimuthAngle = Infinity; // radians
// Set to true to disable use of the keys
this.noKeys = false;
// The four arrow keys
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
// Mouse buttons
this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
////////////
// internals
var scope = this;
var EPS = 0.000001;
var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();
var panStart = new THREE.Vector2();
var panEnd = new THREE.Vector2();
var panDelta = new THREE.Vector2();
var panOffset = new THREE.Vector3();
this.offset = new THREE.Vector3();
var dollyStart = new THREE.Vector2();
var dollyEnd = new THREE.Vector2();
var dollyDelta = new THREE.Vector2();
var phiDelta = 0;
var thetaDelta = 0;
var scale = 1;
var pan = new THREE.Vector3();
var lastPosition = new THREE.Vector3();
var lastQuaternion = new THREE.Quaternion();
var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
var state = STATE.NONE;
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
// so camera.up is the orbit axis
var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
var quatInverse = quat.clone().inverse();
// events
var changeEvent = { type: 'change' };
var startEvent = { type: 'start'};
var endEvent = { type: 'end'};
this.rotateLeft = function ( angle ) {
if ( angle === undefined ) {
angle = getAutoRotationAngle();
}
thetaDelta -= angle;
};
this.rotateUp = function ( angle ) {
if ( angle === undefined ) {
angle = getAutoRotationAngle();
}
phiDelta -= angle;
};
// Fix pan to flat plane
// Works but isn't 1:1 with mouse position so looks weird at times
// http://stackoverflow.com/a/26188674/997339
// pass in distance in world space to move left
this.panLeft = function ( distance ) {
var te = this.object.matrix.elements;
// get elements from the X-column of matrix
panOffset.set( te[ 0 ], 0, te[ 2 ] ).normalize();
panOffset.multiplyScalar( - distance );
pan.add( panOffset );
};
// pass in distance in world space to move forward
this.panUp = function ( distance ) {
var te = this.object.matrix.elements;
// get elements from the Z-column of matrix
panOffset.set( te[ 8 ], 0, te[ 10 ] ).normalize();
panOffset.multiplyScalar( - distance );
pan.add( panOffset );
};
this.panX = function ( distance ) {
panOffset.set( distance, 0, 0 );
pan.add( panOffset );
};
this.panZ = function ( distance ) {
panOffset.set( 0, 0, distance );
pan.add( panOffset );
};
// // pass in distance in world space to move left
// this.panLeft = function ( distance ) {
// var te = this.object.matrix.elements;
// // get X column of matrix
// panOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] );
// panOffset.multiplyScalar( - distance );
// pan.add( panOffset );
// };
// // pass in distance in world space to move up
// this.panUp = function ( distance ) {
// var te = this.object.matrix.elements;
// // get Y column of matrix
// panOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] );
// panOffset.multiplyScalar( distance );
// pan.add( panOffset );
// };
// pass in x,y of change desired in pixel space,
// right and down are positive
this.pan = function ( deltaX, deltaY ) {
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
if ( scope.object.fov !== undefined ) {
// perspective
var position = scope.object.position;
var offset = position.clone().sub( scope.target );
var targetDistance = offset.length();
// half of the fov is center to top of screen
targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
// we actually don't use screenWidth, since perspective camera is fixed to screen height
scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight );
scope.panUp( 2 * deltaY * targetDistance / element.clientHeight );
} else if ( scope.object.top !== undefined ) {
// orthographic
scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth );
scope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight );
} else {
// camera neither orthographic or perspective
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
}
};
this.dollyIn = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale /= dollyScale;
};
this.dollyOut = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale *= dollyScale;
};
this.update = function () {
var position = this.object.position;
this.offset.copy( position ).sub( this.target );
// rotate offset to "y-axis-is-up" space
this.offset.applyQuaternion( quat );
// angle from z-axis around y-axis
var theta = Math.atan2( this.offset.x, this.offset.z );
// angle from y-axis
var phi = Math.atan2( Math.sqrt( this.offset.x * this.offset.x + this.offset.z * this.offset.z ), this.offset.y );
if ( this.autoRotate ) {
this.rotateLeft( getAutoRotationAngle() );
}
theta += thetaDelta;
phi += phiDelta;
// restrict theta to be between desired limits
theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );
// restrict phi to be between desired limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
// restrict phi to be betwee EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
var radius = this.offset.length() * scale;
// restrict radius to be between desired limits
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
// move target to panned location
this.target.add( pan );
this.offset.x = radius * Math.sin( phi ) * Math.sin( theta );
this.offset.y = radius * Math.cos( phi );
this.offset.z = radius * Math.sin( phi ) * Math.cos( theta );
// rotate offset back to "camera-up-vector-is-up" space
this.offset.applyQuaternion( quatInverse );
position.copy( this.target ).add( this.offset );
this.object.lookAt( this.target );
thetaDelta = 0;
phiDelta = 0;
scale = 1;
pan.set( 0, 0, 0 );
// update condition is:
// min(camera displacement, camera rotation in radians)^2 > EPS
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
if ( lastPosition.distanceToSquared( this.object.position ) > EPS
|| 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {
this.dispatchEvent( changeEvent );
lastPosition.copy( this.object.position );
lastQuaternion.copy (this.object.quaternion );
}
};
this.reset = function () {
state = STATE.NONE;
this.target.copy( this.target0 );
this.object.position.copy( this.position0 );
this.update();
};
function getAutoRotationAngle() {
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
}
function getZoomScale() {
// Reduce zoom speed when using touch control
var zoomSpeed = (state === STATE.TOUCH_DOLLY) ? scope.zoomSpeed : scope.zoomSpeed * 0.7;
return Math.pow( 0.95, zoomSpeed );
}
function onMouseDown( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
if ( event.button === scope.mouseButtons.ORBIT ) {
if ( scope.noRotate === true ) return;
state = STATE.ROTATE;
rotateStart.set( event.clientX, event.clientY );
} else if ( event.button === scope.mouseButtons.ZOOM ) {
if ( scope.noZoom === true ) return;
state = STATE.DOLLY;
dollyStart.set( event.clientX, event.clientY );
} else if ( event.button === scope.mouseButtons.PAN ) {
if ( scope.noPan === true ) return;
state = STATE.PAN;
panStart.set( event.clientX, event.clientY );
}
document.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( startEvent );
}
function onMouseMove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
if ( state === STATE.ROTATE ) {
if ( scope.noRotate === true ) return;
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
} else if ( state === STATE.DOLLY ) {
if ( scope.noZoom === true ) return;
dollyEnd.set( event.clientX, event.clientY );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
scope.dollyIn();
} else {
scope.dollyOut();
}
dollyStart.copy( dollyEnd );
} else if ( state === STATE.PAN ) {
if ( scope.noPan === true ) return;
panEnd.set( event.clientX, event.clientY );
panDelta.subVectors( panEnd, panStart );
scope.pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
}
scope.update();
}
function onMouseUp( /* event */ ) {
if ( scope.enabled === false ) return;
document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( endEvent );
state = STATE.NONE;
}
function onMouseWheel( event ) {
if ( scope.enabled === false || scope.noZoom === true ) return;
event.preventDefault();
event.stopPropagation();
var delta = 0;
if ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9
delta = event.wheelDelta;
} else if ( event.detail !== undefined ) { // Firefox
delta = - event.detail;
}
if ( delta > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
scope.update();
scope.dispatchEvent( startEvent );
scope.dispatchEvent( endEvent );
}
function onKeyDown( event ) {
if ( scope.enabled === false || scope.noKeys === true || scope.noPan === true ) return;
switch ( event.keyCode ) {
case scope.keys.UP:
scope.pan( 0, scope.keyPanSpeed );
scope.update();
break;
case scope.keys.BOTTOM:
scope.pan( 0, - scope.keyPanSpeed );
scope.update();
break;
case scope.keys.LEFT:
scope.pan( scope.keyPanSpeed, 0 );
scope.update();
break;
case scope.keys.RIGHT:
scope.pan( - scope.keyPanSpeed, 0 );
scope.update();
break;
}
}
function touchstart( event ) {
if ( scope.enabled === false ) return;
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) return;
state = STATE.TOUCH_ROTATE;
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) return;
state = STATE.TOUCH_DOLLY;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyStart.set( 0, distance );
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) return;
state = STATE.TOUCH_PAN;
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
default:
state = STATE.NONE;
}
scope.dispatchEvent( startEvent );
}
function touchmove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) return;
if ( state !== STATE.TOUCH_ROTATE ) return;
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
scope.update();
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) return;
if ( state !== STATE.TOUCH_DOLLY ) return;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyEnd.set( 0, distance );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
dollyStart.copy( dollyEnd );
scope.update();
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) return;
if ( state !== STATE.TOUCH_PAN ) return;
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
panDelta.subVectors( panEnd, panStart );
scope.pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
scope.update();
break;
default:
state = STATE.NONE;
}
}
function touchend( /* event */ ) {
if ( scope.enabled === false ) return;
scope.dispatchEvent( endEvent );
state = STATE.NONE;
}
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
this.domElement.addEventListener( 'touchstart', touchstart, false );
this.domElement.addEventListener( 'touchend', touchend, false );
this.domElement.addEventListener( 'touchmove', touchmove, false );
window.addEventListener( 'keydown', onKeyDown, false );
// force an update at start
this.update();
};
THREE.MapControls.prototype = Object.create( THREE.EventDispatcher.prototype );

670
src/Vendor/OrbitControls.js vendored 100644
Wyświetl plik

@ -0,0 +1,670 @@
/**
* @author qiao / https://github.com/qiao
* @author mrdoob / http://mrdoob.com
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
* @author erich666 / http://erichaines.com
*/
/*global THREE, console */
// This set of controls performs orbiting, dollying (zooming), and panning. It maintains
// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is
// supported.
//
// Orbit - left mouse / touch: one finger move
// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
// Pan - right mouse, or arrow keys / touch: three finter swipe
//
// This is a drop-in replacement for (most) TrackballControls used in examples.
// That is, include this js file and wherever you see:
// controls = new THREE.TrackballControls( camera );
// controls.target.z = 150;
// Simple substitute "OrbitControls" and the control should work as-is.
THREE.OrbitControls = function ( object, domElement ) {
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
// API
// Set to false to disable this control
this.enabled = true;
// "target" sets the location of focus, where the control orbits around
// and where it pans with respect to.
this.target = new THREE.Vector3();
// center is old, deprecated; use "target" instead
this.center = this.target;
// This option actually enables dollying in and out; left as "zoom" for
// backwards compatibility
this.noZoom = false;
this.zoomSpeed = 1.0;
// Limits to how far you can dolly in and out
this.minDistance = 0;
this.maxDistance = Infinity;
// Set to true to disable this control
this.noRotate = false;
this.rotateSpeed = 1.0;
// Set to true to disable this control
this.noPan = false;
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
// Set to true to automatically rotate around the target
this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
// How far you can orbit vertically, upper and lower limits.
// Range is 0 to Math.PI radians.
this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians
// How far you can orbit horizontally, upper and lower limits.
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
this.minAzimuthAngle = - Infinity; // radians
this.maxAzimuthAngle = Infinity; // radians
// Set to true to disable use of the keys
this.noKeys = false;
// The four arrow keys
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
// Mouse buttons
this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
////////////
// internals
var scope = this;
var EPS = 0.000001;
var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();
var panStart = new THREE.Vector2();
var panEnd = new THREE.Vector2();
var panDelta = new THREE.Vector2();
var panOffset = new THREE.Vector3();
this.offset = new THREE.Vector3();
var dollyStart = new THREE.Vector2();
var dollyEnd = new THREE.Vector2();
var dollyDelta = new THREE.Vector2();
var phiDelta = 0;
var thetaDelta = 0;
var scale = 1;
var pan = new THREE.Vector3();
var lastPosition = new THREE.Vector3();
var lastQuaternion = new THREE.Quaternion();
var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
var state = STATE.NONE;
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
// so camera.up is the orbit axis
var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
var quatInverse = quat.clone().inverse();
// events
var changeEvent = { type: 'change' };
var startEvent = { type: 'start'};
var endEvent = { type: 'end'};
this.rotateLeft = function ( angle ) {
if ( angle === undefined ) {
angle = getAutoRotationAngle();
}
thetaDelta -= angle;
};
this.rotateUp = function ( angle ) {
if ( angle === undefined ) {
angle = getAutoRotationAngle();
}
phiDelta -= angle;
};
// pass in distance in world space to move left
this.panLeft = function ( distance ) {
var te = this.object.matrix.elements;
// get X column of matrix
panOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] );
panOffset.multiplyScalar( - distance );
pan.add( panOffset );
};
// pass in distance in world space to move up
this.panUp = function ( distance ) {
var te = this.object.matrix.elements;
// get Y column of matrix
panOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] );
panOffset.multiplyScalar( distance );
pan.add( panOffset );
};
this.panX = function ( distance ) {
panOffset.set( distance, 0, 0 );
pan.add( panOffset );
};
this.panZ = function ( distance ) {
panOffset.set( 0, 0, distance );
pan.add( panOffset );
};
// pass in x,y of change desired in pixel space,
// right and down are positive
this.pan = function ( deltaX, deltaY ) {
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
if ( scope.object.fov !== undefined ) {
// perspective
var position = scope.object.position;
var offset = position.clone().sub( scope.target );
var targetDistance = offset.length();
// half of the fov is center to top of screen
targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
// we actually don't use screenWidth, since perspective camera is fixed to screen height
scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight );
scope.panUp( 2 * deltaY * targetDistance / element.clientHeight );
} else if ( scope.object.top !== undefined ) {
// orthographic
scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth );
scope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight );
} else {
// camera neither orthographic or perspective
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
}
};
this.dollyIn = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale /= dollyScale;
};
this.dollyOut = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale *= dollyScale;
};
this.update = function () {
var position = this.object.position;
this.offset.copy( position ).sub( this.target );
// rotate offset to "y-axis-is-up" space
this.offset.applyQuaternion( quat );
// angle from z-axis around y-axis
var theta = Math.atan2( this.offset.x, this.offset.z );
// angle from y-axis
var phi = Math.atan2( Math.sqrt( this.offset.x * this.offset.x + this.offset.z * this.offset.z ), this.offset.y );
if ( this.autoRotate ) {
this.rotateLeft( getAutoRotationAngle() );
}
theta += thetaDelta;
phi += phiDelta;
// restrict theta to be between desired limits
theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );
// restrict phi to be between desired limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
// restrict phi to be betwee EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
var radius = this.offset.length() * scale;
// restrict radius to be between desired limits
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
// move target to panned location
this.target.add( pan );
this.offset.x = radius * Math.sin( phi ) * Math.sin( theta );
this.offset.y = radius * Math.cos( phi );
this.offset.z = radius * Math.sin( phi ) * Math.cos( theta );
// rotate offset back to "camera-up-vector-is-up" space
this.offset.applyQuaternion( quatInverse );
position.copy( this.target ).add( this.offset );
this.object.lookAt( this.target );
thetaDelta = 0;
phiDelta = 0;
scale = 1;
pan.set( 0, 0, 0 );
// update condition is:
// min(camera displacement, camera rotation in radians)^2 > EPS
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
if ( lastPosition.distanceToSquared( this.object.position ) > EPS
|| 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {
this.dispatchEvent( changeEvent );
lastPosition.copy( this.object.position );
lastQuaternion.copy (this.object.quaternion );
}
};
this.reset = function () {
state = STATE.NONE;
this.target.copy( this.target0 );
this.object.position.copy( this.position0 );
this.update();
};
function getAutoRotationAngle() {
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
}
function getZoomScale() {
// Reduce zoom speed when using touch control
var zoomSpeed = (state === STATE.TOUCH_DOLLY) ? scope.zoomSpeed : scope.zoomSpeed * 0.7;
return Math.pow( 0.95, zoomSpeed );
}
function onMouseDown( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
if ( event.button === scope.mouseButtons.ORBIT ) {
if ( scope.noRotate === true ) return;
state = STATE.ROTATE;
rotateStart.set( event.clientX, event.clientY );
} else if ( event.button === scope.mouseButtons.ZOOM ) {
if ( scope.noZoom === true ) return;
state = STATE.DOLLY;
dollyStart.set( event.clientX, event.clientY );
} else if ( event.button === scope.mouseButtons.PAN ) {
if ( scope.noPan === true ) return;
state = STATE.PAN;
panStart.set( event.clientX, event.clientY );
}
document.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( startEvent );
}
function onMouseMove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
if ( state === STATE.ROTATE ) {
if ( scope.noRotate === true ) return;
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
} else if ( state === STATE.DOLLY ) {
if ( scope.noZoom === true ) return;
dollyEnd.set( event.clientX, event.clientY );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
scope.dollyIn();
} else {
scope.dollyOut();
}
dollyStart.copy( dollyEnd );
} else if ( state === STATE.PAN ) {
if ( scope.noPan === true ) return;
panEnd.set( event.clientX, event.clientY );
panDelta.subVectors( panEnd, panStart );
scope.pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
}
scope.update();
}
function onMouseUp( /* event */ ) {
if ( scope.enabled === false ) return;
document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( endEvent );
state = STATE.NONE;
}
function onMouseWheel( event ) {
if ( scope.enabled === false || scope.noZoom === true ) return;
event.preventDefault();
event.stopPropagation();
var delta = 0;
if ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9
delta = event.wheelDelta;
} else if ( event.detail !== undefined ) { // Firefox
delta = - event.detail;
}
if ( delta > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
scope.update();
scope.dispatchEvent( startEvent );
scope.dispatchEvent( endEvent );
}
function onKeyDown( event ) {
if ( scope.enabled === false || scope.noKeys === true || scope.noPan === true ) return;
switch ( event.keyCode ) {
case scope.keys.UP:
scope.pan( 0, scope.keyPanSpeed );
scope.update();
break;
case scope.keys.BOTTOM:
scope.pan( 0, - scope.keyPanSpeed );
scope.update();
break;
case scope.keys.LEFT:
scope.pan( scope.keyPanSpeed, 0 );
scope.update();
break;
case scope.keys.RIGHT:
scope.pan( - scope.keyPanSpeed, 0 );
scope.update();
break;
}
}
function touchstart( event ) {
if ( scope.enabled === false ) return;
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) return;
state = STATE.TOUCH_ROTATE;
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) return;
state = STATE.TOUCH_DOLLY;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyStart.set( 0, distance );
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) return;
state = STATE.TOUCH_PAN;
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
default:
state = STATE.NONE;
}
scope.dispatchEvent( startEvent );
}
function touchmove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) return;
if ( state !== STATE.TOUCH_ROTATE ) return;
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
scope.update();
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) return;
if ( state !== STATE.TOUCH_DOLLY ) return;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyEnd.set( 0, distance );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
dollyStart.copy( dollyEnd );
scope.update();
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) return;
if ( state !== STATE.TOUCH_PAN ) return;
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
panDelta.subVectors( panEnd, panStart );
scope.pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
scope.update();
break;
default:
state = STATE.NONE;
}
}
function touchend( /* event */ ) {
if ( scope.enabled === false ) return;
scope.dispatchEvent( endEvent );
state = STATE.NONE;
}
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
this.domElement.addEventListener( 'touchstart', touchstart, false );
this.domElement.addEventListener( 'touchend', touchend, false );
this.domElement.addEventListener( 'touchmove', touchmove, false );
window.addEventListener( 'keydown', onKeyDown, false );
// force an update at start
this.update();
};
THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );

41
src/Vizi.js 100644
Wyświetl plik

@ -0,0 +1,41 @@
/* globals window */
/**
* Namespace for ViziCities
* @author Robin Hawkes - vizicities.com
*/
// Hack to give worker access to VIZI global
if (typeof window === undefined) {
var VIZI;
}
(function() {
"use strict";
var _VIZI = {
VERSION: "0.2.0",
DEBUG: false
};
// Output ASCII logo
console.log("═════════════════════════════════════════════════════════════");
console.log("██╗ ██╗██╗███████╗██╗ ██████╗██╗████████╗██╗███████╗███████╗");
console.log("██║ ██║██║╚══███╔╝██║██╔════╝██║╚══██╔══╝██║██╔════╝██╔════╝");
console.log("██║ ██║██║ ███╔╝ ██║██║ ██║ ██║ ██║█████╗ ███████╗");
console.log("╚██╗ ██╔╝██║ ███╔╝ ██║██║ ██║ ██║ ██║██╔══╝ ╚════██║");
console.log(" ╚████╔╝ ██║███████╗██║╚██████╗██║ ██║ ██║███████╗███████║");
console.log(" ╚═══╝ ╚═╝╚══════╝╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝");
console.log("═══════════════════════════ " + _VIZI.VERSION + " ═══════════════════════════");
// List any constants or helper functions here, like:
// https://github.com/mrdoob/three.js/blob/master/src/Three.js
// Hack to give worker access to VIZI global
if (typeof window === undefined) {
// Expose VIZI to the window
window.VIZI = _VIZI;
} else {
VIZI = _VIZI;
}
}());

Wyświetl plik

@ -0,0 +1,67 @@
/* globals window, _, VIZI, THREE */
/**
* Basic camera
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Camera = function(options) {
if (VIZI.DEBUG) console.log("Initialising VIZI.Camera");
var self = this;
self.options = options || {};
_.defaults(self.options, {
fov: 40,
near: 2,
far: 40000,
position: new VIZI.Point(260, 600, 550),
target: new VIZI.Point()
});
if (!self.options.aspect) {
throw new Error("Required aspect option missing");
}
self.camera = new THREE.PerspectiveCamera(self.options.fov, self.options.aspect, self.options.near, self.options.far);
// It's assumed that you'd want to do this after adding a camera
// TODO: Consider if calling lookAt() here is a step too far and should be left to the user
self.moveTo(self.options.position);
self.lookAt(self.options.target);
};
VIZI.Camera.prototype.addToScene = function(scene) {
var self = this;
scene.add(self.camera);
};
VIZI.Camera.prototype.moveTo = function(point) {
var self = this;
self.camera.position.x = point.x;
self.camera.position.y = point.y;
self.camera.position.z = point.z;
};
VIZI.Camera.prototype.moveBy = function(delta) {
var self = this;
self.camera.position.x += delta.x;
self.camera.position.y += delta.y;
self.camera.position.z += delta.z;
};
VIZI.Camera.prototype.lookAt = function(point) {
var self = this;
self.camera.lookAt(new THREE.Vector3(point.x, point.y, point.z));
};
VIZI.Camera.prototype.changeAspect = function(ratio) {
var self = this;
self.camera.aspect = ratio;
self.camera.updateProjectionMatrix();
};
})();

70
src/WebGL/Layer.js 100644
Wyświetl plik

@ -0,0 +1,70 @@
/* globals window, _, VIZI, THREE */
/**
* 3D layer
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Layer = function() {
if (VIZI.DEBUG) console.log("Initialising VIZI.Layer");
var self = this;
VIZI.EventEmitter.call(self);
self.object = new THREE.Object3D();
self.hidden = false;
};
VIZI.Layer.prototype = Object.create( VIZI.EventEmitter.prototype );
VIZI.Layer.prototype.addToWorld = function(world) {
var self = this;
self.beforeAdd(world);
world.addLayer(self);
self.onAdd(world);
};
VIZI.Layer.prototype.beforeAdd = function(world) {};
VIZI.Layer.prototype.onAdd = function(world) {};
VIZI.Layer.prototype.add = function(object) {
var self = this;
self.object.add(object);
};
VIZI.Layer.prototype.remove = function(object) {
var self = this;
self.object.remove(object);
};
// UI handlers
VIZI.Layer.prototype.hide = function() {
var self = this;
self.hidden = true;
self.object.visible = false;
self.onHide();
};
VIZI.Layer.prototype.show = function() {
var self = this;
self.hidden = false;
self.object.visible = true;
self.onShow();
};
VIZI.Layer.prototype.onHide = function() {};
VIZI.Layer.prototype.onShow = function() {};
VIZI.Layer.prototype.applyVertexColors = function( geom, colour ) {
geom.faces.forEach( function( f ) {
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
for( var j = 0; j < n; j ++ ) {
f.vertexColors[ j ] = colour;
}
} );
};
})();

240
src/WebGL/Scene.js 100644
Wyświetl plik

@ -0,0 +1,240 @@
/* globals window, _, VIZI, THREE */
/**
* 3D scene controller
* @author Robin Hawkes - vizicities.com
*/
(function() {
"use strict";
VIZI.Scene = function(options) {
if (VIZI.DEBUG) console.log("Initialising VIZI.Scene");
var self = this;
self.options = options || {};
_.defaults(self.options, {
antialias: false,
fogColour: 0xffffff,
suppressRenderer: false,
picking: false
});
if (!self.options.viewport) {
throw new Error("Required viewport option missing");
}
self.scene = self.createScene();
self.renderer = self.createRenderer();
self.pickingScene;
self.pickingTexture;
self.pickingMaterial;
self.pickingGeom;
self.pickingMesh;
self.pickingColourID;
self.pickingColour;
self.pickingRef;
if (self.options.picking) {
self.pickingScene = new THREE.Scene();
self.pickingTexture = new THREE.WebGLRenderTarget(self.options.viewport.clientWidth, self.options.viewport.clientHeight);
self.pickingTexture.generateMipmaps = false;
self.pickingMaterial = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors,
// TODO: Remove reliance on making things double-sided to make up for meshes created with incorrect wising
side: THREE.DoubleSide
});
self.pickingGeom = new THREE.Geometry();
self.pickingMesh;
// Start at 1 because default pixel value is 0 (black)
self.pickingColourID = 1;
self.pickingColour = new THREE.Color();
self.pickingRef = {};
}
};
VIZI.Scene.prototype.createScene = function() {
var self = this;
var scene = new THREE.Scene();
// TODO: Fog distance should be an option
scene.fog = new THREE.Fog(self.options.fogColour, 1, 15000);
// TODO: Make this more customisable, perhaps as a "day/night" option
// - I'm sure people would want to add their own lighting too
// TODO: Should this even be in here?
var directionalLight = new THREE.DirectionalLight( 0x999999 );
directionalLight.intesity = 0.1;
directionalLight.position.x = 1;
directionalLight.position.y = 1;
directionalLight.position.z = 1;
scene.add(directionalLight);
var directionalLight2 = new THREE.DirectionalLight( 0x999999 );
directionalLight2.intesity = 0.1;
directionalLight2.position.x = -1;
directionalLight2.position.y = 1;
directionalLight2.position.z = -1;
scene.add(directionalLight2);
return scene;
};
VIZI.Scene.prototype.createRenderer = function() {
var self = this;
var renderer;
if (self.options.suppressRenderer) {
// Mock renderer for tests
// TODO: Should really remove this or fix the tests
renderer = {
setSize: function(){},
setClearColor: function(){},
render: function(){},
domElement: document.createElement("canvas")
};
} else {
renderer = new THREE.WebGLRenderer({
antialias: self.options.antialias,
domElement: document.createElement("canvas")
});
}
renderer.setSize(self.options.viewport.clientWidth, self.options.viewport.clientHeight);
renderer.setClearColor(self.scene.fog.color, 1);
// Gamma settings make things look 'nicer' for some reason
renderer.gammaInput = true;
renderer.gammaOutput = true;
self.options.viewport.appendChild(renderer.domElement);
return renderer;
};
VIZI.Scene.prototype.add = function(object) {
var self = this;
self.scene.add(object);
};
VIZI.Scene.prototype.addPickable = function(mesh, id) {
var self = this;
if (!self.options.picking) {
return;
}
// Generate unique colour
self.pickingColour.setHex(self.pickingColourID);
// Apply colour to geom
// TODO: Does this cause issues with anything else using the geom reference?
self.applyVertexColors(mesh.geometry, self.pickingColour);
// Remove mesh from picking scene
self.pickingScene.remove(self.pickingMesh);
// Add geom to merged geom
self.pickingGeom.merge(mesh.geometry, mesh.matrix);
// Store reference to id and colour
self.pickingRef[self.pickingColourID] = {
id: id,
mesh: mesh
};
self.pickingMesh = new THREE.Mesh(self.pickingGeom, self.pickingMaterial);
// Update mesh in picking scene
self.pickingScene.add(self.pickingMesh);
// Increment picking colour ID
self.pickingColourID++;
};
VIZI.Scene.prototype.removePickable = function(id) {
var self = this;
if (!self.options.picking) {
return;
}
// TODO: Remove pickable geom from merged geom
// TODO: Remove reference to id and colour
// TODO: Update mesh in picking scene
};
VIZI.Scene.prototype.getPickable = function(id) {
var self = this;
if (!self.options.picking) {
return;
}
return self.pickingRef[id];
};
VIZI.Scene.prototype.remove = function(object) {
var self = this;
self.scene.remove(object);
};
VIZI.Scene.prototype.render = function(camera) {
var self = this;
if (!self.scene) {
throw new Error("Scene is required for render");
}
if (!camera) {
throw new Error("Camera is required for render");
}
self.renderer.render(self.scene, camera.camera);
};
VIZI.Scene.prototype.renderPicking = function(camera) {
var self = this;
if (!self.options.picking) {
return;
}
if (!self.pickingScene) {
throw new Error("Picking scene is required for render");
}
if (!camera) {
throw new Error("Camera is required for render");
}
self.renderer.render(self.pickingScene, camera.camera, self.pickingTexture);
};
// TODO: Update picking scene on resize
VIZI.Scene.prototype.resize = function(width, height) {
var self = this;
self.renderer.setSize(width, height);
};
// TODO: This is duplicated from VIZI.Layer, find a way to merge
VIZI.Scene.prototype.applyVertexColors = function( geom, colour ) {
geom.faces.forEach( function( f ) {
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
for( var j = 0; j < n; j ++ ) {
f.vertexColors[ j ] = colour;
}
} );
};
})();

Wyświetl plik

@ -1,23 +0,0 @@
/* globals window, _, VIZI */
(function() {
"use strict";
// Animation methods and logic
VIZI.Animation = (function() {
// Easing formulas based on:
// http://joshondesign.com/2013/03/01/improvedEasingEquations
var easing = {
cubicIn: function(t) {
return Math.pow(t,3);
},
cubicInOut: function(t) {
if(t < 0.5) return easing.cubicIn(t*2.0)/2.0;
return 1-easing.cubicIn((1-t)*2)/2;
}
};
return {
easing: easing
};
}());
}());

Wyświetl plik

@ -1,18 +0,0 @@
/* globals window, _, VIZI, Q */
(function() {
"use strict";
VIZI.Cache = function() {
_.extend(this, VIZI.Mediator);
this.data = {};
};
VIZI.Cache.prototype.get = function(key) {
return this.data[key];
};
VIZI.Cache.prototype.add = function(key, value) {
this.data[key] = value;
};
}());

Wyświetl plik

@ -1,346 +0,0 @@
/* globals window, _, VIZI, Q */
(function() {
"use strict";
VIZI.City = function() {
VIZI.Log("Inititialising city");
_.extend(this, VIZI.Mediator);
// Debug tools
this.dat = undefined;
this.fps = undefined;
this.rendererInfo = undefined;
// Options
this.options = undefined;
// UI
this.ui = {};
this.ui.loading = undefined;
this.ui.attribution = undefined;
this.ui.osmEdit = undefined;
// Geo methods
this.geo = undefined;
// Grid manager
this.grid = undefined;
// Data gathering and processing
this.data = undefined;
// Basic WebGL components (scene, camera, renderer, lights, etc)
this.webgl = undefined;
// DOM - elements and events (window resize, etc)
this.domElement = undefined;
this.domEvents = undefined;
// Controls (mouse, keyboard, Leap, etc)
this.controls = undefined;
// Core city-scene objects (floor, skybox, etc)
this.floor = undefined;
// Main application loop
this.loop = undefined;
this.publish("addToDat", this, {name: "City", properties: ["init"]});
this.subscribe("hashchange", this.onHashchange);
};
VIZI.City.prototype.init = function(options) {
VIZI.Log("Loading city");
var startTime = Date.now();
var self = this;
var deferred = Q.defer();
if (!options) {
options = {};
}
self.options = options;
var hash = window.location.hash.replace('#', '');
var coordCheck = /^(\-?\d+(\.\d+)?),(\-?\d+(\.\d+)?)$/;
if (coordCheck.test(hash)) {
options.coords = hash.split(',').reverse();
}
_.defaults(options, {
coords: [-0.01924, 51.50358],
capZoom: true,
capOrbit: true,
overpass: true,
overpassGridUpdate: true,
overpassWayIntersect: false,
controls: { enable: true }
});
// Output city options
VIZI.Log(options);
// Set up geo methods
self.geo = VIZI.Geo.getInstance({
center: options.coords
});
// Store DOM reference
self.domElement = self.options.domElement;
// Load city using promises
self.publish("loadingProgress", 0);
// Initialise loading UI
self.initLoadingUI().then(function() {
self.publish("loadingProgress", 0.1);
// Initialise debug tools
return self.initDebug();
}).then(function() {
self.publish("loadingProgress", 0.15);
// Initialise attribution and OSM edit UI
var promises = [];
// Initialise DOM events
promises.push(self.initAttributionUI());
// Initialise controls
promises.push(self.initOSMEditUI());
return Q.allSettled(promises);
}).then(function() {
self.publish("loadingProgress", 0.25);
// Initialise WebGL
return self.initWebGL(options);
}).then(function() {
self.publish("loadingProgress", 0.3);
var promises = [];
// Initialise DOM events
promises.push(self.initDOMEvents());
// Initialise controls
promises.push(self.initControls());
return Q.allSettled(promises);
}).then(function() {
self.publish("loadingProgress", 0.4);
// Initialise grid manager
return self.initGrid();
}).then(function() {
self.publish("loadingProgress", 0.5);
// TODO: Work out a way to use progress event of each promises to increment loading progress
// Perhaps by looping through each promises individually and working out progress fraction by num. of promises / amount processed
// Load objects using promises
var promises = [];
// Load core city objects
promises.push(self.loadCoreObjects());
// Load data from the OSM Overpass API
// Set up data loader
if (options.overpass) {
self.data = new VIZI.DataOverpass({
gridUpdate: options.overpassGridUpdate
});
promises.push(self.loadOverpass(options.overpassWayIntersect));
}
return Q.allSettled(promises);
}).then(function (results) {
// Set up and start application loop
self.loop = new VIZI.Loop();
self.publish("loadingProgress", 1);
self.publish("loadingComplete");
VIZI.Log("Finished loading city in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initAttributionUI = function() {
var startTime = Date.now();
var deferred = Q.defer();
this.ui.attribution = new VIZI.Attribution();
this.ui.attribution.init().then(function(result) {
VIZI.Log("Finished intialising attribution UI in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initOSMEditUI = function() {
var startTime = Date.now();
var deferred = Q.defer();
this.ui.osmEdit = new VIZI.OSMEdit();
this.ui.osmEdit.init().then(function(result) {
VIZI.Log("Finished intialising OSM edit UI in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initLoadingUI = function() {
var startTime = Date.now();
var deferred = Q.defer();
this.ui.loading = new VIZI.Loading();
this.ui.loading.init(this.domElement).then(function(result) {
VIZI.Log("Finished intialising loading UI in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initDebug = function() {
VIZI.Log("Intialising debug tools");
var startTime = Date.now();
if (VIZI.DEBUG) {
this.dat = new VIZI.Dat();
this.fps = new VIZI.FPS();
this.rendererInfo = new VIZI.RendererInfo();
}
VIZI.Log("Finished intialising debug tools in " + (Date.now() - startTime) + "ms");
return Q.fcall(function() {});
};
// TODO: Move set up of core objects out to somewhere else
VIZI.City.prototype.initWebGL = function(options) {
var startTime = Date.now();
var deferred = Q.defer();
this.webgl = new VIZI.WebGL();
this.webgl.init(this.domElement, this.geo.centerPixels, options.capZoom, options.capOrbit).then(function(result) {
VIZI.Log("Finished intialising WebGL in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initDOMEvents = function() {
var startTime = Date.now();
var deferred = Q.defer();
this.domEvents = new VIZI.DOMEvents();
this.domEvents.init().then(function(result) {
VIZI.Log("Finished intialising DOM events in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initControls = function() {
var startTime = Date.now();
var deferred = Q.defer();
this.controls = VIZI.Controls.getInstance();
this.controls.init(this.domElement, this.webgl.camera, this.options.controls).then(function(result) {
VIZI.Log("Finished intialising controls in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.initGrid = function() {
var startTime = Date.now();
var deferred = Q.defer();
// Set up grid manager
this.grid = VIZI.Grid.getInstance();
this.grid.init(this.geo.center).then(function(result) {
VIZI.Log("Finished intialising grid manager in " + (Date.now() - startTime) + "ms");
deferred.resolve();
});
return deferred.promise;
};
VIZI.City.prototype.loadCoreObjects = function() {
VIZI.Log("Loading core objects");
var startTime = Date.now();
// Set up core components
this.floor = new VIZI.Floor();
VIZI.Log("Finished loading core objects in " + (Date.now() - startTime) + "ms");
return Q.fcall(function() {});
};
VIZI.City.prototype.loadOverpass = function(wayIntersect) {
VIZI.Log("Loading data from OSM Overpass API");
var startTime = Date.now();
// var deferred = Q.defer();
if (wayIntersect) {
this.data.updateByWayIntersect(wayIntersect).done(function() {
VIZI.Log("Finished loading Overpass data using way intersection in " + (Date.now() - startTime) + "ms");
});
} else {
this.data.update().done(function() {
VIZI.Log("Finished loading Overpass data in " + (Date.now() - startTime) + "ms");
// deferred.resolve();
});
}
// return deferred.promise;
return Q.fcall(function() {});
};
VIZI.City.prototype.onHashchange = function(){
window.location.reload();
};
}());

Some files were not shown because too many files have changed in this diff Show More