├── geomancer ├── mancers │ ├── __init__.py │ ├── geotype.py │ ├── bea.py │ ├── usa_spending.py │ ├── base.py │ ├── bls.py │ ├── geotype_us.py │ ├── census_reporter.py │ ├── wazimap.py │ └── census_reporter_us.py ├── result_folder │ └── .gitkeep ├── static │ ├── images │ │ ├── ap-logo.png │ │ ├── favicon.ico │ │ ├── red_mage.gif │ │ ├── black_mage.gif │ │ ├── white_mage.gif │ │ ├── cfafrica-logo.png │ │ ├── knight-logo.jpg │ │ ├── geomancer-logo.png │ │ ├── geomancer_format.jpg │ │ ├── red_mage_animated.gif │ │ ├── black_mage_animated.gif │ │ └── white_mage_animated.gif │ ├── css │ │ ├── images │ │ │ ├── spritesheet.png │ │ │ └── spritesheet-2x.png │ │ ├── bootstrap-nav-wizard.css │ │ └── custom.css │ └── js │ │ ├── analytics_lib.js │ │ ├── jquery.spin.js │ │ ├── jquery.cookie.js │ │ ├── spin.min.js │ │ ├── ejs_production.js │ │ └── moment.min.js ├── templates │ ├── 404.html │ ├── error.html │ ├── 413.html │ ├── wizard_base.html │ ├── index.html │ ├── geographies.html │ ├── data-sources.html │ ├── upload-formats.html │ ├── upload.html │ ├── geomance.html │ ├── base.html │ ├── select_geo.html │ ├── select_tables.html │ └── contribute-data.html ├── app_config.py.example ├── __init__.py ├── redis_session.py ├── api.py ├── helpers.py ├── views.py └── worker.py ├── opt_requirements.txt ├── examples ├── act.xlsx ├── FEMARecoupment.xlsx ├── fdic_failed_banks.xlsx ├── Eqi_results_2013July22.xlsx ├── my_fascinating_county_data.xlsx ├── 2014_ca_county_camp_contribs_by_party.xlsx └── test_geographies.csv ├── .gitignore ├── runworker.py ├── requirements.txt ├── runserver.py ├── LICENSE └── README.md /geomancer/mancers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /geomancer/result_folder/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /opt_requirements.txt: -------------------------------------------------------------------------------- 1 | raven==5.1.1 2 | blinker==1.3 3 | -------------------------------------------------------------------------------- /examples/act.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/examples/act.xlsx -------------------------------------------------------------------------------- /examples/FEMARecoupment.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/examples/FEMARecoupment.xlsx -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .DS_Store 3 | app_config.py 4 | use_cases 5 | .env 6 | *.csv 7 | dump.rdb 8 | geomancer/result_folder/* -------------------------------------------------------------------------------- /examples/fdic_failed_banks.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/examples/fdic_failed_banks.xlsx -------------------------------------------------------------------------------- /examples/Eqi_results_2013July22.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/examples/Eqi_results_2013July22.xlsx -------------------------------------------------------------------------------- /geomancer/static/images/ap-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/ap-logo.png -------------------------------------------------------------------------------- /geomancer/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/favicon.ico -------------------------------------------------------------------------------- /geomancer/static/images/red_mage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/red_mage.gif -------------------------------------------------------------------------------- /geomancer/static/images/black_mage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/black_mage.gif -------------------------------------------------------------------------------- /geomancer/static/images/white_mage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/white_mage.gif -------------------------------------------------------------------------------- /examples/my_fascinating_county_data.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/examples/my_fascinating_county_data.xlsx -------------------------------------------------------------------------------- /geomancer/static/images/cfafrica-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/cfafrica-logo.png -------------------------------------------------------------------------------- /geomancer/static/images/knight-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/knight-logo.jpg -------------------------------------------------------------------------------- /geomancer/static/css/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/css/images/spritesheet.png -------------------------------------------------------------------------------- /geomancer/static/images/geomancer-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/geomancer-logo.png -------------------------------------------------------------------------------- /geomancer/static/css/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/css/images/spritesheet-2x.png -------------------------------------------------------------------------------- /geomancer/static/images/geomancer_format.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/geomancer_format.jpg -------------------------------------------------------------------------------- /geomancer/static/images/red_mage_animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/red_mage_animated.gif -------------------------------------------------------------------------------- /runworker.py: -------------------------------------------------------------------------------- 1 | from geomancer.worker import queue_daemon 2 | from geomancer import create_app 3 | 4 | app = create_app() 5 | 6 | queue_daemon(app) 7 | -------------------------------------------------------------------------------- /geomancer/static/images/black_mage_animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/black_mage_animated.gif -------------------------------------------------------------------------------- /geomancer/static/images/white_mage_animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/geomancer/static/images/white_mage_animated.gif -------------------------------------------------------------------------------- /examples/2014_ca_county_camp_contribs_by_party.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeForAfrica/geomancer/master/examples/2014_ca_county_camp_contribs_by_party.xlsx -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.10.1 2 | csvkit==0.9.0 3 | redis==2.10.1 4 | scrapelib==0.10.1 5 | gunicorn==19.1.1 6 | xlwt==0.7.5 7 | us==0.9.0 8 | lxml==3.4.0 9 | requests==2.3.0 10 | pandas==0.16.0 -------------------------------------------------------------------------------- /runserver.py: -------------------------------------------------------------------------------- 1 | from geomancer import create_app 2 | 3 | app = create_app() 4 | 5 | if __name__ == "__main__": 6 | import sys 7 | try: 8 | port = int(sys.argv[1]) 9 | except IndexError: 10 | port = 5000 11 | app.run(host='0.0.0.0', port=port) 12 | -------------------------------------------------------------------------------- /geomancer/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Page Not Found - Geomancer{% endblock %} 3 | {% block content %} 4 |
What you were looking for is just not there.
6 | 7 | {% endblock %} -------------------------------------------------------------------------------- /geomancer/templates/error.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}Error - Geomancer{% endblock %} 3 | {% block content %} 4 |Oops! There was an error.
6 | 7 |If this issue persists, contact the system administrator.
8 | {% endblock %} -------------------------------------------------------------------------------- /geomancer/templates/413.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block title %}File too large - Geomancer{% endblock %} 3 | {% block content %} 4 |The file you tried to upload was too large for us to handle
6 | 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /geomancer/app_config.py.example: -------------------------------------------------------------------------------- 1 | from os.path import join, abspath, dirname 2 | 3 | SECRET_KEY = 'your secret key here' 4 | CACHE_DIR = '/tmp' 5 | REDIS_QUEUE_KEY = 'geomancer' 6 | RESULT_FOLDER = abspath(join(dirname(__file__), 'result_folder')) 7 | MAX_CONTENT_LENGTH = 10 * 1024 * 1024 # 10mb 8 | ALLOWED_EXTENSIONS = set(['csv', 'xls', 'xlsx']) 9 | SENTRY_DSN = '' 10 | 11 | MANCERS = ( 12 | 'geomancer.mancers.census_reporter.CensusReporter', 13 | 'geomancer.mancers.bea.BureauEconomicAnalysis', 14 | 'geomancer.mancers.bls.BureauLaborStatistics' 15 | ) 16 | 17 | # key = mancer machine_name, val = API key 18 | MANCER_KEYS = { 19 | 'bureau_economic_analysis' : None, # register at http://bea.gov/API/signup/index.cfm 20 | 'bureau_labor_statistics' : None # register at http://data.bls.gov/registrationEngine/ 21 | } 22 | -------------------------------------------------------------------------------- /geomancer/templates/wizard_base.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% block content %} 3 |
8 | Add geographically-related data to any spreadsheet.
9 | 10 | 11 | 12 |All you need is a spreadsheet that includes a column about a location, like city, state or congressional district.
13 | 14 |Take a look at the data sources and geographies we support.
15 | 16 |Interested in integrating Geomancer into an application? Check out the API!
21 |Geomancer currently has data for {{ geographies | length }} kinds of geographies. Take a look at the types below, along with the kinds of data we support.
17 | 18 | {% for g in geographies %} 19 || Formatting notes | 24 |{{g['info']['formatting_notes']}} | 25 |
| Example | 28 |{{g['info']['formatting_example']}} | 29 |
Data available for {{g['info']['human_name']}}
34 || Data available | 38 |Source | 39 |
|---|---|
| {{ table.human_name }} | 45 |{{ table.source_name }} | 46 |
Geomancer currently has data from {{ data_sources | length }} sources.
17 |Is there data that your newsroom would find useful, that isn't already here? You can adapt Geomancer by adding datasets/columns from existing data sources, or by adding a completely new data source.
18 | Learn how to contribute > 19 |{{ d.description }}
27 || Datasets available | 31 |Geographies | 32 |
|---|---|
| {{ table.human_name }} | 38 |
39 | {% for geo in table.geo_types %}
40 | {{geo.human_name}} 41 | {% endfor %} 42 | |
43 |
You can import a file of up to 10mb of these file types:
21 | 22 |Only the first sheet will be imported into Geomancer. Also, please make sure that the first row contains header information with column names.
29 | 30 |
31 |
32 | Comma-separated value (.csv) files are a standard way to represent tabular data. Cell values with comma, newline or quotes must be quoted and quotes escaped by doubling. For example: "17"" LCD display".
34 | 35 |By convention, the first row acts as header and defines the names of the columns in the data. However, you can specify which row is the header during import.
36 | 37 |Many of these guidelines were lifted from Google Fusion Tables, which has excellent documentation.
39 |Pick a spreadsheet that includes a column about a location, like city, state or congressional district, and then pick additional data to add about that location.
Take a look at the data sources and geographies we have, or learn how to add your own.
Spreadsheet format (learn more)
27 | 28 | 29 |
30 |
31 |
32 |
10 |
11 |
12 |
13 |
This may take a few minutes. We are fetching data for each row in your spreadsheet.
15 |When finished, your spreadsheet will be available to download below.
16 |For more accuracy, you can select State along with either City, County, Congressional district, or School district.
7 | 36 | {% endblock %} 37 | {% block extra_javascript %} 38 | 104 | {% endblock %} 105 | -------------------------------------------------------------------------------- /geomancer/static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* Space out content a bit */ 2 | body { 3 | padding-bottom: 20px; 4 | font-size: 16px; 5 | } 6 | 7 | table, label,.control-label,.help-block,.checkbox,.radio { font-size: 14px; } 8 | .alert { font-size: 1em; font-weight: 500; } 9 | 10 | .label:hover { text-decoration: none; } 11 | 12 | .showmore-content { 13 | overflow: hidden; 14 | height: 165px; 15 | } 16 | 17 | .showmore-content p { 18 | font-size: 14px; 19 | line-height: 20px; 20 | } 21 | 22 | .showmore, .showless { 23 | margin-top: 10px; 24 | } 25 | 26 | /* Everything but the jumbotron gets side spacing for mobile first views */ 27 | .header, 28 | .marketing, 29 | .footer { 30 | padding-left: 15px; 31 | padding-right: 15px; 32 | } 33 | 34 | /* Custom page header */ 35 | .header { 36 | border-bottom: 1px solid #e5e5e5; 37 | } 38 | /* Make the masthead heading the same height as the navigation */ 39 | .header h3 { 40 | margin-top: 0; 41 | margin-bottom: 0; 42 | line-height: 40px; 43 | padding-bottom: 19px; 44 | } 45 | 46 | /* Custom page footer */ 47 | .footer { 48 | padding-top: 19px; 49 | color: #777; 50 | border-top: 1px solid #e5e5e5; 51 | } 52 | 53 | /* Customize container */ 54 | .container-narrow > hr { 55 | margin: 30px 0; 56 | } 57 | 58 | /* Main marketing message and sign up button */ 59 | .jumbotron { 60 | text-align: center; 61 | border-bottom: 1px solid #e5e5e5; 62 | } 63 | .jumbotron .btn { 64 | font-size: 21px; 65 | padding: 14px 24px; 66 | } 67 | 68 | .jumbotron li { 69 | font-size: 16px; 70 | } 71 | 72 | /* Responsive: Portrait tablets and up */ 73 | @media screen and (min-width: 768px) { 74 | /* Remove the padding we set earlier */ 75 | .header, 76 | .marketing, 77 | .footer { 78 | padding-left: 0; 79 | padding-right: 0; 80 | } 81 | /* Space out the masthead */ 82 | .header { 83 | margin-bottom: 30px; 84 | } 85 | /* Remove the bottom border on the jumbotron for visual effect */ 86 | .jumbotron { 87 | border-bottom: 0; 88 | } 89 | } 90 | 91 | .nowrap { white-space:nowrap; } 92 | 93 | /* MAP styles */ 94 | #map { 95 | min-height: 500px; 96 | } 97 | .leaflet-top.leaflet-left{ 98 | margin-left: 20px; 99 | } 100 | .row.filters { 101 | margin-left: 5px; 102 | } 103 | 104 | /* Datepicker styles */ 105 | 106 | .ui-widget { 107 | font-size: 0.9em; 108 | } 109 | 110 | .ui-datepicker { 111 | width: 22.5%; 112 | height: auto; 113 | } 114 | 115 | .ui-datepicker table { 116 | width: 100%; 117 | background-color: #fff; 118 | } 119 | 120 | .ui-datepicker table td, 121 | .ui-datepicker table th { 122 | padding: 0; 123 | } 124 | 125 | .ui-datepicker-header { 126 | color: #333; 127 | background-color: #DDD; 128 | font-weight: bold; 129 | } 130 | 131 | .ui-datepicker-title { 132 | text-align: center; 133 | line-height: 30px; 134 | } 135 | 136 | .ui-datepicker-prev:hover, 137 | .ui-datepicker-next:hover { 138 | cursor: pointer; 139 | } 140 | 141 | .ui-datepicker-prev { 142 | float: left; 143 | } 144 | 145 | .ui-datepicker-next { 146 | float: right; 147 | margin-right: 5px; 148 | } 149 | 150 | .ui-datepicker-next:after { 151 | content: ""; 152 | border-color: rgba(0,0,0,0) rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) #333; 153 | border-image: none; 154 | border-style: solid; 155 | border-width: 9px; 156 | display: block; 157 | height: 0; 158 | margin-top: 5px; 159 | width: 0; 160 | } 161 | .ui-datepicker-prev:before { 162 | content: ""; 163 | border-color: rgba(0,0,0,0) #333 rgba(0, 0, 0, 0) rgba(0, 0, 0, 0); 164 | border-image: none; 165 | border-style: solid; 166 | border-width: 9px; 167 | display: block; 168 | height: 0; 169 | margin-top: 5px; 170 | width: 0; 171 | } 172 | 173 | .ui-datepicker th { 174 | text-transform: uppercase; 175 | font-size: 11px; 176 | text-align: center; 177 | } 178 | 179 | .ui-datepicker tbody td { 180 | border-right: none; 181 | text-align: center; 182 | padding: 3px 0; 183 | } 184 | .ui-datepicker tbody tr { 185 | border-bottom: 1px solid #bbb; 186 | } 187 | 188 | .ui-datepicker tbody tr:last-child { 189 | border-bottom: 0px 190 | } 191 | 192 | .ui-tooltip { 193 | width: 25%; 194 | overflow: hidden; 195 | } 196 | 197 | /* Response */ 198 | .response-table { 199 | width: 100%; 200 | } 201 | 202 | /* Map legend styles */ 203 | .legend { 204 | line-height: 18px; 205 | color: #555; 206 | background: rgba(255,255,255,0.8); 207 | box-shadow: 0 0 15px rgba(0,0,0,0.2); 208 | border-radius: 5px; 209 | } 210 | 211 | .legend div { 212 | padding: 10px; 213 | } 214 | 215 | .legend i { 216 | width: 18px; 217 | height: 18px; 218 | float: left; 219 | margin-right: 8px; 220 | opacity: 0.7; 221 | } 222 | 223 | /* Collapse */ 224 | .panel-heading{ 225 | cursor: pointer; cursor: hand; 226 | } 227 | 228 | /* api alert */ 229 | #api-alert{ 230 | background-color: #dcf1e4; 231 | font-weight: 200; 232 | } -------------------------------------------------------------------------------- /geomancer/api.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, make_response, request, jsonify, \ 2 | session as flask_session 3 | from geomancer.worker import DelayedResult, do_the_work 4 | from geomancer.helpers import import_class, get_geo_types, get_data_sources 5 | from geomancer.app_config import MANCERS, MANCER_KEYS 6 | from geomancer.mancers.geotype import GeoTypeEncoder 7 | import json 8 | from redis import Redis 9 | from collections import OrderedDict 10 | 11 | redis = Redis() 12 | 13 | api = Blueprint('api', __name__) 14 | 15 | @api.route('/api/geomance/', methods=['POST', 'GET']) 16 | def geomance_api(): 17 | """ 18 | Needs to get the file as well which fields have 19 | geography and what kind of geography they contain. 20 | Should be a multipart POST with the file in the file part 21 | and the field definitions in the form part. 22 | 23 | Field definitions should be in string encoded JSON blob like so: 24 | 25 | { 26 | 10: { 27 | 'type': 'city_state', 28 | 'append_columns': ['total_population', 'median_age'] 29 | } 30 | } 31 | 32 | The key is the zero-indexed position of the columns within the spreadsheet. 33 | The value is a dict containing the geographic type and the columns to 34 | append. The values in that list should be fetched from one of the other 35 | endpoints. 36 | 37 | To mance on a combination of columns, separate the column indexes and 38 | geotypes with a semicolon like so: 39 | 40 | { 41 | 10;2: { 42 | 'type': 'city;state', 43 | 'append_columns': ['total_population', 'median_age'] 44 | } 45 | } 46 | 47 | In this example, column 10 contains the city info and column 2 contains 48 | the state info. 49 | 50 | Responds with a key that can be used to poll for results 51 | """ 52 | 53 | field_defs = json.loads(request.data) 54 | if request.files: 55 | file_contents = request.files['input_file'].read() 56 | filename = request.files['input_file'].filename 57 | else: 58 | file_contents = flask_session['file'] 59 | filename = flask_session['filename'] 60 | session = do_the_work.delay(file_contents, field_defs, filename) 61 | resp = make_response(json.dumps({'session_key': session.key})) 62 | resp.headers['Content-Type'] = 'application/json' 63 | return resp 64 | 65 | @api.route('/api/geomance-results/8 | Is there data that you'd like to add to Geomancer? 9 | We built this as an open, extensible platform, so anyone can contribute. 10 | If you know how to program in Python, you can adapt Geomancer to your needs using the 11 | instructions below. Otherwise, post your request to our 12 | Google Group. 13 |
14 |First, fork the geomancer repository. This requires a GitHub account.
31 |Then, clone your Geomancer fork:
32 |33 | $ git clone https://github.com/YOURGITHUBUSERNAME/geomancer.git 34 | $ cd geomancer35 | 36 |
Make sure OS level dependencies are installed:
40 |Install required python libraries. We recommend using virtualenv and virtualenvwrapper for working in a virtualized development environment. Read how to set up virtualenv.
49 |Once you have virtualenv set up:
50 |51 | $ mkvirtualenv geomancer 52 | $ pip install -r requirements.txt53 |
NOTE: Mac users might need this lxml workaround.
54 |Afterwards, whenever you want to work on geomancer using the virtual environment you created:
55 |$ workon geomancer56 | 57 |
59 | $ cp geomancer/app_config.py.example geomancer/app_config.py60 | In your newly created
app_config.py file, the active data sources are defined by MANCERS. Add any relevant API keys to MANCER_KEYS.
61 |
62 | There are three components that should be running simultaneously for the app to work: Redis, the Flask app, and the worker process that appends to the spreadsheets. For debugging purposes, it is useful to run each of these commands in a separate terminal session.
64 |65 | $ redis-server # This command may differ depending on your OS 66 | $ python runworker.py # starts the worker for processing files 67 | $ python runserver.py # starts the web server68 | 69 |
Open your browser and navigate to http://localhost:5000
70 |If you'd like to share your work with the rest of the world, submit a pull request with your changes!
72 | 73 | 74 | 75 |
92 | Each data source corresponds to a 'mancer' in geomancer/mancers/. For example, the BureauLaborStatistics class in geomancer/mancers/bls.py is the 'mancer' for BLS.
93 |
95 | The datasets and columns that are available to a mancer are defined manually. Mancer datasets usually correspond to tables at the source, and mancer columns correspond to the columns within a table. 96 |
97 |98 | The methods defined for all mancers are: 99 |
get_metadatageo_lookupterm (the original search term) and geoid (the full geographic id to be used by the search method). If need be, this method can look up geographic ids through specific APIs.
107 | search133 | Because the datasets and columns are defined manually, and because of the high granularity of available data, the mancers don't include all possible data from a data source. For example, BLS QCEW data is available for a wide range of geographies and many industries, but the BLS mancer currently only has data at the state level and at the highest industry summary level (all industries). 134 |
135 |
137 | If you're interested in adding data to an existing mancer (say, adding columns with statistics for specific industries to the BLS mancer), all you'll need to do is modify the mancer metadata (defined in the get_metadata method) and ensure that the search method knows how to return the data you've added.
138 |
geomancer/mancers/.
156 |
157 |
159 | Geomancer implements a base class that establishes a pattern for setting up a new data source.
160 | In a new .py file in geomancer/mancers/, inherit from the BaseMancer class like so:
161 |
163 | from geomancer.mancers.base import BaseMancer 164 | 165 | class MyGreatMancer(BaseMancer): 166 | 167 | name = 'My Great Mancer' 168 | machine_name = 'my_great_mancer' 169 | base_url = 'http://lotsadata.gov/api' 170 | info_url = 'http://lotsadata.gov' 171 | description = 'This is probably the best mancer ever written' 172 | 173 | def get_metadata(self): 174 | return 'woo' 175 | 176 | def search(self, geo_ids=None, columns=None): 177 | return 'woo' 178 | 179 | def geo_lookup(self, search_term, geo_type=None): 180 | return 'woo'181 | 182 |
Override the name, machine_name, base_url, info_url, & description properties accordingly.
This is the bulk of the work. You will need to implement the get_metadata, search, & geo_lookup methods.
186 |
187 | Detailed information about how the responses from these 188 | methods should be structured as well as two example mancers 189 | can be found in the 190 | Github repository. 191 |
192 | 193 |The basic configuration options for Geomancer exist in app_config.py. Add the import path to the module where you wrote your mancer and you should start seeing it as an option when you run the app.
195 |
197 | MANCERS = ( 198 | 'geomancer.mancers.census_reporter.CensusReporter', 199 | 'geomancer.mancers.usa_spending.USASpending', 200 | 'geomancer.mancers.my_mancer.MyMancer', 201 | )202 |
If your data source requires an API key, add the API key to app_config.py:
204 | MANCER_KEYS = {
205 | 'my_great_mancer' : 'biGl0ngUu1dT4ing',
206 | }
207 |
208 | The key (i.e. my_great_mancer) should match the value you used for the machine_name property of your mancer class.
209 |
231 | Do you have data with geography types that are not
232 | currently offered by Geomancer? The geography types are built in an extensible way - each
233 | geography is implemented as a GeoType subclass that expects
234 | a few static properties to be overridden:
235 |
237 | from geomancer.mancers.geotype import GeoType 238 | 239 | class WizardSchoolDistrict(GeoType): 240 | human_name = 'Wizard school district' 241 | machine_name = 'wizard_school_district' 242 | formatting_notes = 'Full name of a school district for wizards and witches' 243 | formatting_example = 'Hogwarts School of Witchcraft and Wizardry'244 |
245 | More details on how to implement a new GeoType can be found
246 | here.
247 |