Note
Though lingcod includes several example projects, you are encouraged to create your MarineMap instance as a seperate python package outside of the lingcod source tree. This will allow for clear seperation between the underlying libraries (lingcod) and your implementation of MarineMap (the “project”)
You will need to install lingcod’s dependencies and lingcod itself. For detailed instructions, please follow Getting Started.
In this example, we’ll set up a new MarineMap instance for the state of Oregon. We use django-admin.py to create a standard django project:
cd ~/oregon_stuff
django-admin.py startproject oregon
You should see the following directory structure:
oregon
|-- __init__.py
|-- manage.py
|-- settings.py
`-- urls.py
We now need to configure the settings and urls for our oregon project.
First, while we appreciate django-admin’s attempt at an initial settings.py file, it doesn’t really work for us in this case. Because lincod contains sensible default settings, we only need to worry about MarineMap specific settings and django settings unique to this project. You can delete all the lines in settings.py except for the SECRET_KEY and add the following:
# Django settings for oregon project.
from lingcod.common.default_settings import *
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_NAME = 'oregon'
DATABASE_USER = 'postgres'
TIME_ZONE = 'America/Vancouver'
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
USE_I18N = True
SECRET_KEY = 'keep_the_one_autogenerated_by_django-admin'
WAVE_ID = 'wavesandbox.com!q43w5q3w45taesrfgs' # Your Google Wave Account - may not be needed
ROOT_URLCONF = 'oregon.urls'
TEMPLATE_DIRS = ( os.path.realpath(os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/')), )
INSTALLED_APPS += ( 'mlpa', )
MPA_CLASS = 'mlpa.models.Mpa'
ARRAY_CLASS = 'mlpa.models.MpaArray'
MPA_FORM = 'mlpa.forms.MpaForm'
ARRAY_FORM = 'mlpa.forms.ArrayForm'
Notice the final 5 lines; Here we install an app called ‘mlpa’ and define the classes and forms based on that ‘mlpa’ app. Let’s go ahead and create that app and the proper classes to match our settings.
Lingcod is set up so that MPAs and Arrays are not installed by default. Instead we need need to create our own custom MPA and Array classes specific to this project. Luckily python’s object inheritance makes it easy to use the default MPA and Array behavior if our project does not require extensive customization of these concepts.
First we must create an app to hold our custom MPA and Array information:
cd oregon
python manage.py startapp mlpa
Here we should see the following directory structure created for us:
mlpa
|-- __init__.py
|-- models.py
|-- tests.py
`-- views.py
We can ignore the tests and views for now; for now we’ll focus on creating the Mpa and MpaArray models. Open mlpa/models.py and add:
from lingcod.mpa.models import Mpa as BaseMpa
from lingcod.array.models import MpaArray as BaseMpaArray
class Mpa(BaseMpa):
pass
class MpaArray(BaseMpaArray):
pass
You can see that we merely took the abstract base classes from lingcod which define the default behavior and created our own classes based on them. If you need to customize the behavior, you can extend the models here instead of simply ‘pass’ing.
Finally we’ll need to create some django forms for Mpa and MpaArray objects. These define how the editing interfaces will appear in MarineMap. Create a new file mlpa/forms.py and add:
from lingcod.mpa.forms import MpaForm as BaseMpaForm
from lingcod.array.forms import ArrayForm as BaseArrayForm
from models import Mpa, MpaArray
class ArrayForm(BaseArrayForm):
class Meta(BaseArrayForm.Meta):
model = MpaArray
exclude = ('sharing_groups',)
class MpaForm(BaseMpaForm):
class Meta:
model = Mpa
exclude = ('sharing_groups','content_type','object_id',)
This is slightly more involved but the concept is similar to the classes - we take the default behavior of lingcod’s Mpa and Array forms and extend them for this project.
In order for django to successfully route requests, we need to define URL patterns for the common lingcod operations. Modify your urls.py to show the following:
from django.conf.urls.defaults import *
from django.conf import settings
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'lingcod.common.views.map', {'template_name': 'common/map.html'}, name="map"),
(r'^tests/', 'django.views.generic.simple.direct_to_template', {'template': 'common/tests.html', 'extra_context': {'api_key': settings.GOOGLE_API_KEY}}),
(r'^layers/', include('lingcod.layers.urls')),
(r'^studyregion/', include('lingcod.studyregion.urls')),
(r'^faq/', include('lingcod.simplefaq.urls')),
(r'^help/', include('lingcod.help.urls')),
(r'^kml/', include('lingcod.kmlapp.urls')),
(r'^manipulators/', include('lingcod.manipulators.urls')),
(r'^mpas/', include('lingcod.mpa.urls')),
(r'^arrays/', include('lingcod.array.urls')),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'next_page': settings.LOGIN_REDIRECT_URL}, name='auth_logout'),
(r'^accounts/profile/', include('lingcod.user_profile.urls')),
(r'^accounts/', include('lingcod.common.registration_backend.urls')),
(r'^intersection/', include('lingcod.intersection.urls')),
(r'^screencasts/', include('lingcod.screencasts.urls')),
(r'^sharing/', include('lingcod.sharing.urls')),
(r'^staticmap/', include('lingcod.staticmap.urls')),
(r'^news/', include('lingcod.news.urls')),
(r'^admin/', include(admin.site.urls)),
)
# Useful for serving files when using the django dev server
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True }),
)
Next we’ll create a new postgis-enabled database for this project and use django’s syncdb command to create the necessary tables. Assuming you installed postgis functions, etc into your postgres template1, this is as simple as:
createdb oregon -U postgres
Every project needs to define a study region. This is a (multi)polygon shape which defines where shapes can be created. Because new shapes are clipped to this study region boundary, it is highly recomended to give this step great consideration up front; changing the study region boundary at a later date is MUCH more complicated.
Let’s assume that we have created a shapefile containing a single polyon feature representing the waters within 5 kilometers of the oregon coast. This shapefile is in UTM Zone 10N, WGS84 datum which corresponds to the SRID 32610 (see http://www.spatialreference.org/ref/epsg/32610/). This is also the projection we want to use for storing our shapes so we’ll add this to our settings.py:
GEOMETRY_DB_SRID = 32610
First we have to create some necessary table in the database:
python manage.py syncdb
python manage.py migrate
Next, we’ll use some custom lingcod management commands to load up our carefully and meticulously created study region:
python manage.py create_study_region --name oregon_coast data/oregon_study_region.shp
python manage.py change_study_region 1
We need to put our mlpa app under migration which ensures that future changes to the MLPA models’ schema get reflected in the database:
python manage.py schemamigration --initial mlpa
python manage.py migrate mlpa --fake
All static media is split between the project and the lingcod library. The project media goes in a ‘media’ directory at the same level as your project directory. (ie ~/oregon_stuff/oregon/ is your django project, ~/oregon_stuff/media is your oregon media dir). First you must define the MEDIA_ROOT in our settings.py file:
MEDIA_ROOT = '/var/www/oregon_media'
The install_media command will then take all files from lingcod media and oregon media directories and combine them into this directory. It is safe to assume that when you deploy marinemap you’ll want this directory to be fully web accessible:
python manage.py install_media
This step also compresses all js and css using the django-compress app to ensure that your js and css are single compact files to maximize performance.
For now, we’ll just test our new project using django’s built-in development server. First we need to set up the sites framework so that our domain is accurate for any absolute urls created by our MarineMap project. Then run the dev server to test it:
python manage.py site_setup_for_dev
python manage.py sharing_setup
python manage.py runserver
Our Oregon MarineMap project should now be accessible at http://localhost:8000/
MarineMap has fixtures containing test data that is installed on database setup like an example Study Region and Data Layers. This makes it easy to verify the installation and learn how the tool works. For use in an actual planning session these default datasets will need to be replaced.
See the documentation in the following sections to customize MarineMap as needed:
The setup this guide has walked through only specifies how to run the django development server. To setup a public facing website using Apache, consult the Deployment notes.