Skip to content

Commit

Permalink
Add web interface
Browse files Browse the repository at this point in the history
  • Loading branch information
invisibleroads committed Jul 24, 2014
1 parent a177e92 commit 7e2e306
Show file tree
Hide file tree
Showing 20 changed files with 510 additions and 33 deletions.
18 changes: 14 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
*.swp
*.pyc
*-secret.ini
*.db
*.db-journal
*.egg
*.egg-info
*.lprof
*.log
*.lprof
*.py[co]
*.sw[op]
*.tmp
*~
.coverage
.ipynb_checkpoints
ConvNet__*
build
data_*
dist
launch*.ini
sdist
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0.0
---
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include *.ini *.cfg *.md
recursive-include count_buildings *.mako *.css *.js *.ico *.png
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
Count buildings in satellite image
==================================
Estimate the number of buildings in a satellite image.
Reveal population density.


Run scripts
-----------

get_tiles_from_image.py
get_points_from_tiles.py

get_examples_from_points.py
get_dataset_from_examples.py
get_batches_from_datasets.py
get_marker_from_dataset.py

get_array_shape_from_batches.py
get_index_from_batches.py

get_arrays_from_image.py
get_batches_from_arrays.py
get_predictions_from_arrays.py
get_counts_from_predictions.py


Launch interface
----------------

ENV=~/.virtualenvs/crosscompute
virtualenv $ENV
source $ENV/bin/activate
pip install -U crosscompute

cd ~/Projects/count-buildings
python setup.py develop
pserve development.ini
8 changes: 3 additions & 5 deletions TODO.goals
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# US/Pacific 7/23/2014
# US/Pacific 7/24/2014
= Deploy web app
= Write dummy web app for uploading a request and downloading the response
Write dummy processor that takes a request and returns a response
Replace dummy proccesor with real processor
= Replace dummy proccesor with real processor
Feature Modi Research Group logo and link on tool webpage
Improve development classifier
Consider optimizing get_counts by searching maximums locally
Expand All @@ -17,4 +15,4 @@ Make scripts easier to use
Send access credentials to all tools, valid with no membership fee for one year
Add payment
Mask paths in run.pkl
Evaluate classifiers on cost-effective lower resolution satellite images
Evaluate classifiers on cost-effective lower resolution satellite images
6 changes: 5 additions & 1 deletion TODO.log
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# UTC 07/23/2014
# UTC 07/24/2014
+ Write dummy web app for uploading a request and downloading the response [07/24/2014]
+ Update description [07/24/2014]
+ Let user paste image URL [07/24/2014]
+ Trigger rqworker that downloads and gets file size [07/24/2014]
+ Investigate why the positive count is 7027 instead of 7028 [07/23/2014]
+ Prepare small test geotiff [07/23/2014]
+ Finish crosscompute-scaffolds [07/23/2014]
Expand Down
24 changes: 24 additions & 0 deletions count_buildings/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from pyramid.config import Configurator

from . import view


def describe():
return dict(
route=view.ROUTE_NAME,
title=view.PACKAGE_TITLE)


def includeme(config):
config.scan()
config.include(view)
config.add_static_view(
view.ROUTE_NAME + '/_',
view.PACKAGE_NAME + ':assets', cache_max_age=3600)


def main(global_config, **settings):
config = Configurator(settings=settings)
config.include('crosscompute')
includeme(config)
return config.make_wsgi_app()
41 changes: 41 additions & 0 deletions count_buildings/assets/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require.config({
paths: {
common: static_url + 'common'
}
});
require(['common'], function(common) {
require(['cc'], function(cc) {

$('#classifier_name_question').show().find('select').click(function() {
$('#image_url_question, #run').reveal();
});

$('#run').click(function() {

if (!window.user_id) {
window.location = login_url;
return false;
}

$('#run').prop('disabled', true);

var $target = $('#target_table').html('Counting buildings...').reveal();
$('html').animate({scrollTop: $target.offset().top}, 500);

cc.post(run_url, {
classifier_name: $('#classifier_name').val(),
image_url: $('#image_url').val()
}, {
end: true
}, function(result) {
var summary = result.summary;
var columns = summary.columns, rows = summary.rows;
$target
.data('result_id', result.id)
.fill_table(columns, rows);
$('#run').prop('disabled', false);
});
});

});
});
50 changes: 50 additions & 0 deletions count_buildings/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import sys
from os import makedirs
from os.path import basename, join
from tempfile import mkstemp
from urllib2 import urlopen

from count_buildings.scripts.get_tiles_from_image import save_image_properties
from crosscompute.libraries import script
from crosscompute.libraries import queue


CLASSIFIER_FOLDER = '/tmp/classifiers'
DOWNLOAD_FOLDER = '/tmp/downloads'
try:
makedirs(DOWNLOAD_FOLDER)
except OSError:
pass


def start(argv=sys.argv):
with script.Starter(run, argv) as starter:
starter.add_argument(
'--classifier_name', metavar='NAME', required=True)
starter.add_argument(
'--image_url', metavar='NAME', required=True)


def schedule(target_result_id, classifier_name, image_url):
target_folder = script.get_target_folder(target_result_id)
summary = run(target_folder, classifier_name, image_url)
queue.save(target_result_id, summary)


def run(target_folder, classifier_name, image_url):
# classifier_path = join(CLASSIFIER_FOLDER, classifier_name)
image_path = download(image_url)
image_name = basename(image_url)
image_properties = save_image_properties(image_path)
return dict(
columns=['Dimensions', 'Bands'],
rows=[[
image_name,
'%ix%im' % tuple(image_properties['image_dimensions']),
image_properties['image_band_count']]])


def download(url):
path = mkstemp(dir=DOWNLOAD_FOLDER)[1]
open(path, 'wb').write(urlopen(url).read())
return path
4 changes: 2 additions & 2 deletions count_buildings/scripts/get_arrays_from_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from crosscompute.libraries import script

from .get_examples_from_points import get_pixel_centers
from .get_tiles_from_image import save_image_dimensions
from .get_tiles_from_image import save_image_properties
from ..libraries.kdtree import KDTree
from ..libraries.satellite_image import ImageScope
from ..libraries.satellite_image import SatelliteImage
Expand Down Expand Up @@ -43,7 +43,7 @@ def run(
tile_dimensions, overlap_dimensions,
included_pixel_bounds):
if tile_dimensions is None and included_pixel_bounds is None:
return save_image_dimensions(image_path)
return save_image_properties(image_path)
elif tile_dimensions is None:
return save_pixel_bounds(
target_folder, image_path, included_pixel_bounds)
Expand Down
2 changes: 1 addition & 1 deletion count_buildings/scripts/get_marker_from_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import sys
from crosscompute.libraries import script

from .get_dataset_from_examples import DATASET_NAME
from ..libraries.markers import initialize_marker
from ..libraries.dataset import DATASET_NAME


def start(argv=sys.argv):
Expand Down
10 changes: 0 additions & 10 deletions count_buildings/scripts/get_pixel_bounds_from_image.py

This file was deleted.

4 changes: 2 additions & 2 deletions count_buildings/scripts/get_tiles_from_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def run(
tile_dimensions, overlap_dimensions, tile_indices,
included_pixel_bounds, list_pixel_bounds):
if tile_dimensions is None and included_pixel_bounds is None:
return save_image_dimensions(image_path)
return save_image_properties(image_path)
elif tile_dimensions is None:
return save_pixel_bounds(
target_folder, image_path, included_pixel_bounds)
Expand All @@ -50,7 +50,7 @@ def run(
included_pixel_bounds, list_pixel_bounds)


def save_image_dimensions(image_path):
def save_image_properties(image_path):
image = satellite_image.SatelliteImage(image_path)
return dict(
image_dimensions=image.to_dimensions(image.pixel_dimensions),
Expand Down
42 changes: 42 additions & 0 deletions count_buildings/show.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<%! script_url = '/count-buildings/_/main' %>
<%inherit file='crosscompute:templates/base.mako'/>

<h1>${title}</h1>
<p>Reveal regional population density.</p>

<form id=questions role=form>

<div id=classifier_name_question class=form-group>
<label for=classifier_name class=control-label>Which classifier will we use?</label>
<select id=classifier_name class=form-control>
<option value='myanmar4-20140708-001953'>myanmar4</option>
<option value='uganda1-20140715-061930'>uganda1</option>
</select>
</div>

<div id=image_url_question class=form-group>
<label for=image_url class=control-label>From which URL will we download the image?</label>
<input id=image_url type=text class=form-control value='http://backpack.invisibleroads.com/count-buildings/images/myanmar4-201200,2314700,201500,2314400.tif'>
</div>

<button id=run type=button class='btn btn-primary'>Count buildings</button>

</form>

<div id=results>
<table id=target_table class=table></table>
<button type=button class='btn btn-success download'>Download</button>
</div>

<div id=acknowledgments>
Thanks to
<a target=_blank href=https://github.com/sherpashaky>Shaky Sherpa</a>,
<a target=_blank href=http://www.earth.columbia.edu/articles/view/2770>Vijay Modi</a>,
<a target=_blank href=https://code.google.com/u/108586368378757621796/>Alex Krizhevsky</a>,
<a target=_blank href=https://github.com/dnouri>Daniel Nouri</a> and
<a target=_blank href=http://www.cs.toronto.edu/~ilya/<a/>Ilya Sutskever</a>.
</div>

<script>
var run_url = '${request.route_path("count-buildings")}';
</script>
Loading

0 comments on commit 7e2e306

Please sign in to comment.