├── .gitignore ├── LICENSE ├── README.md ├── dajaxice ├── __init__.py ├── core │ ├── Dajaxice.py │ └── __init__.py ├── decorators.py ├── exceptions.py ├── finders.py ├── models.py ├── templates │ └── dajaxice │ │ ├── dajaxice.core.js │ │ ├── dajaxice_function_loop.js │ │ └── dajaxice_module_loop.js ├── templatetags │ ├── __init__.py │ └── dajaxice_templatetags.py ├── tests │ ├── __init__.py │ ├── ajax.py │ ├── requirements.txt │ └── urls.py ├── urls.py ├── utils.py └── views.py ├── example ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png └── 6.png ├── giscube ├── __init__.py ├── config.py ├── settings.py ├── urls.py └── wsgi.py ├── giscube_app ├── __init__.py ├── ajax.py ├── forms.py ├── models.py ├── scripts │ ├── __init__.py │ ├── clip_geotiff_by_shp.py │ ├── conversion.py │ ├── data_management.py │ ├── extract_shp_table.py │ ├── gtif_to_tile.py │ ├── metadata.py │ ├── open_file.py │ ├── opendap.py │ ├── spatial_analysis.py │ └── what_file.py ├── static │ ├── css │ │ ├── .DS_Store │ │ ├── OpenLayer_style.css │ │ ├── bootstrap-glyphicons.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── bootstrap_2.3.css │ │ ├── jquery.fileupload-ui.css │ │ ├── jquery.fileupload.css │ │ ├── leaflet-0.6.4_leaflet.css │ │ ├── leaflet-0.6.4_leaflet.ie.css │ │ ├── ol.css │ │ ├── side_menu.css │ │ └── style.css │ ├── db.sqlite3 │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── img │ │ ├── .DS_Store │ │ ├── giscube.svg │ │ ├── github.png │ │ ├── glyphicons-halflings-white.png │ │ ├── glyphicons-halflings.png │ │ ├── logo.png │ │ └── logo_beta.png │ ├── js │ │ ├── .DS_Store │ │ ├── KML.js │ │ ├── OpenLayers.js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── collapse.js │ │ ├── jquery.fileupload-process.js │ │ ├── jquery.fileupload-ui.js │ │ ├── jquery.fileupload.js │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ ├── jquery.ui.widget.js │ │ ├── jquery.xdr-transport.js │ │ ├── kml-layer.js │ │ ├── leaflet-0.6.4_leaflet.js │ │ ├── leaflet.filelayer.js │ │ ├── main.js │ │ ├── ol.js │ │ ├── togeojson.js │ │ └── transition.js │ └── uploaded_files │ │ └── .DS_Store ├── templates │ ├── data_information │ │ └── index.html │ ├── data_resource │ │ └── index.html │ ├── data_visualiser │ │ └── index.html │ ├── footer.html │ ├── header.html │ └── tools │ │ ├── buffer_shp.html │ │ ├── clip_geotiff_by_shp.html │ │ ├── color_table_geotiff.html │ │ ├── coord_to_point_shp.html │ │ ├── extract_shp_table.html │ │ ├── geotiff_resolution.html │ │ ├── geotiff_to_kml.html │ │ ├── index.html │ │ ├── ncdump_header.html │ │ ├── ncdump_whole_netcdf.html │ │ ├── netcdf_to_geojson.html │ │ ├── netcdf_to_geotiff.html │ │ ├── point_inside_shapefile.html │ │ ├── re_project_geotiff.html │ │ ├── re_project_shapefile.html │ │ ├── shp_to_json.html │ │ ├── shp_to_kml.html │ │ ├── shp_to_tif.html │ │ ├── tif_to_point_json.html │ │ └── tif_to_point_shp.html ├── templatetags │ ├── __init__.py │ ├── extract_shp_table.py │ ├── nc_dict.py │ ├── netcdf_dict.py │ ├── re-project.py │ ├── shp_dict.py │ └── tif_dict.py ├── urls.py └── views.py ├── manage.py └── vagrant.zip /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | bin/ 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | eggs/ 14 | lib/ 15 | lib64/ 16 | parts/ 17 | sdist/ 18 | var/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | 23 | # Installer logs 24 | pip-log.txt 25 | pip-delete-this-directory.txt 26 | 27 | # Unit test / coverage reports 28 | .tox/ 29 | .coverage 30 | .cache 31 | nosetests.xml 32 | coverage.xml 33 | 34 | # Translations 35 | *.mo 36 | 37 | *.nc 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | [Demo video](http://youtu.be/iV7SvP-gil4) 4 | ======= 5 | 6 | ##Web Based GIS Application 7 | 8 | 9 | Beside some open source GIS libraries and some software like ArcGIS there are comparatively few open source, web-based and easy to use application that are capable of doing GIS processing and visualization. To address this, we present GISCube, an open source web-based GIS application that can store, visualize and process GIS and GeoSpatial data. GISCube is powered by [Geothon](https://github.com/MBoustani/Geothon), an open source python GIS cookbook. Geothon has a variety of Geoprocessing tools such data conversion, processing, spatial analysis and data management tools. GISCube has the capability of supporting a variety of well known GIS data formats in both vector and raster formats, and the system is being expanded to support NASA’s and scientific data formats such as netCDF and HDF files. 10 | 11 | 12 | ##Installation (vagrant) 13 | 14 | 1- [Install Vagrant (v 1.8.1)](https://docs.vagrantup.com/v2/installation/) 15 | 16 | 2- [Install VirtualBox (v 5.0.16)](https://www.virtualbox.org/wiki/Downloads) 17 | 18 | 3- Download [vagrant.zip](https://github.com/MBoustani/GISCube/blob/master/vagrant.zip?raw=true) 19 | 20 | 4- Unzip vagrant.zip 21 | 22 | 5- `cd vagrant` 23 | 24 | 6- `vagrant up` 25 | 26 | 7-`vagrant ssh` 27 | 28 | 8- `cd GISCube` 29 | 30 | 9- `python manage.py runserver 0.0.0.0:5050` 31 | 32 | 10- open [localhost:5050](http://localhost:5050) in browser and enjoy. 33 | 34 | 11- To exit the VM (vagrant) type `exit` 35 | 36 | 12- To remove/destroy VM, exit vagarnat first then type `vagrant destroy` 37 | 38 | ##Documentation 39 | [Documentation](https://github.com/MBoustani/GISCube/wiki) 40 | 41 | ##Example 42 | In this example, we are going to use "Clip GeoTIIF" tool to clip a GeoTIFF using Shapefile. 43 | [Example](https://github.com/MBoustani/GISCube/wiki/Example) 44 | -------------------------------------------------------------------------------- /dajaxice/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = (0, 7, 'beta') 2 | -------------------------------------------------------------------------------- /dajaxice/core/Dajaxice.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from django.utils.importlib import import_module 4 | 5 | log = logging.getLogger('dajaxice') 6 | 7 | 8 | class DajaxiceFunction(object): 9 | """ Basic representation of a dajaxice ajax function.""" 10 | 11 | def __init__(self, function, name, method): 12 | self.function = function 13 | self.name = name 14 | self.method = method 15 | 16 | def call(self, *args, **kwargs): 17 | """ Call the function. """ 18 | return self.function(*args, **kwargs) 19 | 20 | 21 | class DajaxiceModule(object): 22 | """ Basic representation of a dajaxice module. """ 23 | 24 | def __init__(self, name=None): 25 | self.name = name 26 | self.functions = {} 27 | self.submodules = {} 28 | 29 | def add(self, name, function): 30 | """ Add this function at the ``name`` deep. If the submodule already 31 | exists, recusively call the add method into the submodule. If not, 32 | create the module and call the add method.""" 33 | 34 | # If this is not the final function name (there are more modules) 35 | # split the name again an register a new submodule. 36 | if '.' in name: 37 | module, extra = name.split('.', 1) 38 | if module not in self.submodules: 39 | self.submodules[module] = DajaxiceModule(module) 40 | self.submodules[module].add(extra, function) 41 | else: 42 | self.functions[name] = function 43 | 44 | 45 | class Dajaxice(object): 46 | 47 | def __init__(self): 48 | self._registry = {} 49 | self._modules = None 50 | 51 | def register(self, function, name=None, method='POST'): 52 | """ 53 | Register this function as a dajaxice function. 54 | 55 | If no name is provided, the module and the function name will be used. 56 | The final (customized or not) must be unique. """ 57 | 58 | method = self.clean_method(method) 59 | 60 | # Generate a default name 61 | if not name: 62 | module = ''.join(str(function.__module__).rsplit('.ajax', 1)) 63 | name = '.'.join((module, function.__name__)) 64 | 65 | if ':' in name: 66 | log.error('Ivalid function name %s.' % name) 67 | return 68 | 69 | # Check for already registered functions 70 | if name in self._registry: 71 | log.error('%s was already registered.' % name) 72 | return 73 | 74 | # Create the dajaxice function. 75 | function = DajaxiceFunction(function=function, 76 | name=name, 77 | method=method) 78 | 79 | # Register this new ajax function 80 | self._registry[name] = function 81 | 82 | def is_callable(self, name, method): 83 | """ Return if the function callable or not. """ 84 | return name in self._registry and self._registry[name].method == method 85 | 86 | def clean_method(self, method): 87 | """ Clean the http method. """ 88 | method = method.upper() 89 | if method not in ['GET', 'POST']: 90 | method = 'POST' 91 | return method 92 | 93 | def get(self, name): 94 | """ Return the dajaxice function.""" 95 | return self._registry[name] 96 | 97 | @property 98 | def modules(self): 99 | """ Return an easy to loop module hierarchy with all the functions.""" 100 | if not self._modules: 101 | self._modules = DajaxiceModule() 102 | for name, function in self._registry.items(): 103 | self._modules.add(name, function) 104 | return self._modules 105 | 106 | LOADING_DAJAXICE = False 107 | 108 | 109 | def dajaxice_autodiscover(): 110 | """ 111 | Auto-discover INSTALLED_APPS ajax.py modules and fail silently when 112 | not present. NOTE: dajaxice_autodiscover was inspired/copied from 113 | django.contrib.admin autodiscover 114 | """ 115 | global LOADING_DAJAXICE 116 | if LOADING_DAJAXICE: 117 | return 118 | LOADING_DAJAXICE = True 119 | 120 | import imp 121 | from django.conf import settings 122 | 123 | for app in settings.INSTALLED_APPS: 124 | 125 | try: 126 | app_path = import_module(app).__path__ 127 | except AttributeError: 128 | continue 129 | 130 | try: 131 | imp.find_module('ajax', app_path) 132 | except ImportError: 133 | continue 134 | 135 | import_module("%s.ajax" % app) 136 | 137 | LOADING_DAJAXICE = False 138 | -------------------------------------------------------------------------------- /dajaxice/core/__init__.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from Dajaxice import Dajaxice, dajaxice_autodiscover 4 | 5 | 6 | class DajaxiceConfig(object): 7 | """ Provide an easy to use way to read the dajaxice configuration and 8 | return the default values if no configuration is present.""" 9 | 10 | default_config = {'DAJAXICE_XMLHTTPREQUEST_JS_IMPORT': True, 11 | 'DAJAXICE_JSON2_JS_IMPORT': True, 12 | 'DAJAXICE_EXCEPTION': 'DAJAXICE_EXCEPTION', 13 | 'DAJAXICE_MEDIA_PREFIX': 'dajaxice'} 14 | 15 | def __getattr__(self, name): 16 | """ Return the customized value for a setting (if it exists) or the 17 | default value if not. """ 18 | 19 | if name in self.default_config: 20 | if hasattr(settings, name): 21 | return getattr(settings, name) 22 | return self.default_config.get(name) 23 | return None 24 | 25 | @property 26 | def dajaxice_url(self): 27 | return r'^%s/' % self.DAJAXICE_MEDIA_PREFIX 28 | 29 | @property 30 | def django_settings(self): 31 | return settings 32 | 33 | @property 34 | def modules(self): 35 | return dajaxice_functions.modules 36 | 37 | dajaxice_functions = Dajaxice() 38 | dajaxice_config = DajaxiceConfig() 39 | -------------------------------------------------------------------------------- /dajaxice/decorators.py: -------------------------------------------------------------------------------- 1 | import functools 2 | 3 | from dajaxice.core import dajaxice_functions 4 | 5 | 6 | def dajaxice_register(*dargs, **dkwargs): 7 | """ Register some function as a dajaxice function 8 | 9 | For legacy purposes, if only a function is passed register it a simple 10 | single ajax function using POST, i.e: 11 | 12 | @dajaxice_register 13 | def ajax_function(request): 14 | ... 15 | 16 | After 0.5, dajaxice allow to customize the http method and the final name 17 | of the registered function. This decorator covers both the legacy and 18 | the new functionality, i.e: 19 | 20 | @dajaxice_register(method='GET') 21 | def ajax_function(request): 22 | ... 23 | 24 | @dajaxice_register(method='GET', name='my.custom.name') 25 | def ajax_function(request): 26 | ... 27 | 28 | You can also register the same function to use a different http method 29 | and/or use a different name. 30 | 31 | @dajaxice_register(method='GET', name='users.get') 32 | @dajaxice_register(method='POST', name='users.update') 33 | def ajax_function(request): 34 | ... 35 | """ 36 | 37 | if len(dargs) and not dkwargs: 38 | function = dargs[0] 39 | dajaxice_functions.register(function) 40 | return function 41 | 42 | def decorator(function): 43 | @functools.wraps(function) 44 | def wrapper(request, *args, **kwargs): 45 | return function(request, *args, **kwargs) 46 | dajaxice_functions.register(function, *dargs, **dkwargs) 47 | return wrapper 48 | return decorator 49 | -------------------------------------------------------------------------------- /dajaxice/exceptions.py: -------------------------------------------------------------------------------- 1 | class DajaxiceError(Exception): 2 | pass 3 | 4 | 5 | class FunctionNotCallableError(DajaxiceError): 6 | pass 7 | 8 | 9 | class DajaxiceImportError(DajaxiceError): 10 | pass 11 | -------------------------------------------------------------------------------- /dajaxice/finders.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tempfile 3 | 4 | from django.contrib.staticfiles import finders 5 | from django.template import Context 6 | from django.template.loader import get_template 7 | from django.core.exceptions import SuspiciousOperation 8 | 9 | 10 | class VirtualStorage(finders.FileSystemStorage): 11 | """" Mock a FileSystemStorage to build tmp files on demand.""" 12 | 13 | def __init__(self, *args, **kwargs): 14 | self._files_cache = {} 15 | super(VirtualStorage, self).__init__(*args, **kwargs) 16 | 17 | def get_or_create_file(self, path): 18 | if path not in self.files: 19 | return '' 20 | 21 | data = getattr(self, self.files[path])() 22 | 23 | try: 24 | current_file = open(self._files_cache[path]) 25 | current_data = current_file.read() 26 | current_file.close() 27 | if current_data != data: 28 | os.remove(path) 29 | raise Exception("Invalid data") 30 | except Exception: 31 | handle, tmp_path = tempfile.mkstemp() 32 | tmp_file = open(tmp_path, 'w') 33 | tmp_file.write(data) 34 | tmp_file.close() 35 | self._files_cache[path] = tmp_path 36 | 37 | return self._files_cache[path] 38 | 39 | def exists(self, name): 40 | return name in self.files 41 | 42 | def listdir(self, path): 43 | folders, files = [], [] 44 | for f in self.files: 45 | if f.startswith(path): 46 | f = f.replace(path, '', 1) 47 | if os.sep in f: 48 | folders.append(f.split(os.sep, 1)[0]) 49 | else: 50 | files.append(f) 51 | return folders, files 52 | 53 | def path(self, name): 54 | try: 55 | path = self.get_or_create_file(name) 56 | except ValueError: 57 | raise SuspiciousOperation("Attempted access to '%s' denied." % name) 58 | return os.path.normpath(path) 59 | 60 | 61 | class DajaxiceStorage(VirtualStorage): 62 | 63 | files = {os.path.join('dajaxice', 'dajaxice.core.js'): 'dajaxice_core_js'} 64 | 65 | def dajaxice_core_js(self): 66 | from dajaxice.core import dajaxice_autodiscover, dajaxice_config 67 | 68 | dajaxice_autodiscover() 69 | 70 | c = Context({'dajaxice_config': dajaxice_config}) 71 | return get_template(os.path.join('dajaxice', 'dajaxice.core.js')).render(c) 72 | 73 | 74 | class DajaxiceFinder(finders.BaseStorageFinder): 75 | storage = DajaxiceStorage() 76 | -------------------------------------------------------------------------------- /dajaxice/models.py: -------------------------------------------------------------------------------- 1 | # Don't delete me 2 | -------------------------------------------------------------------------------- /dajaxice/templates/dajaxice/dajaxice_function_loop.js: -------------------------------------------------------------------------------- 1 | {% for function_name, function in module.functions.items %} 2 | {{ function_name }}: function(callback_function, argv, custom_settings){ 3 | return Dajaxice.call('{{ function.name }}', '{{ function.method }}', callback_function, argv, custom_settings); 4 | }{% if not forloop.last or top or module.submodules %},{% endif %} 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /dajaxice/templates/dajaxice/dajaxice_module_loop.js: -------------------------------------------------------------------------------- 1 | {{ name }}: { 2 | {% include "dajaxice/dajaxice_function_loop.js" %} 3 | {% with parent_foorloop=forloop %} 4 | {% for name, sub_module in module.submodules.items %} 5 | {% with filename="dajaxice/dajaxice_module_loop.js" module=sub_module %} 6 | {% include filename %} 7 | {% endwith %} 8 | {% if not forloop.last %},{% endif %} 9 | {% endfor %} 10 | } 11 | {% endwith %} 12 | -------------------------------------------------------------------------------- /dajaxice/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/dajaxice/templatetags/__init__.py -------------------------------------------------------------------------------- /dajaxice/templatetags/dajaxice_templatetags.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from django import template 4 | from django.middleware.csrf import get_token 5 | from django.conf import settings 6 | from django.core.files.storage import get_storage_class 7 | 8 | staticfiles_storage = get_storage_class(settings.STATICFILES_STORAGE)() 9 | 10 | register = template.Library() 11 | 12 | log = logging.getLogger('dajaxice') 13 | 14 | 15 | @register.simple_tag(takes_context=True) 16 | def dajaxice_js_import(context, csrf=True): 17 | """ Return the js script tag for the dajaxice.core.js file 18 | If the csrf argument is present and it's ``nocsrf`` dajaxice will not 19 | try to mark the request as if it need the csrf token. By default use 20 | the dajaxice_js_import template tag will make django set the csrftoken 21 | cookie on the current request.""" 22 | 23 | csrf = csrf != 'nocsrf' 24 | request = context.get('request') 25 | 26 | if request and csrf: 27 | get_token(request) 28 | elif csrf: 29 | log.warning("The 'request' object must be accesible within the " 30 | "context. You must add 'django.contrib.messages.context" 31 | "_processors.request' to your TEMPLATE_CONTEXT_PROCESSORS " 32 | "and render your views using a RequestContext.") 33 | 34 | url = staticfiles_storage.url('dajaxice/dajaxice.core.js') 35 | return '' % url 36 | -------------------------------------------------------------------------------- /dajaxice/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | from django.conf import settings 4 | 5 | from dajaxice.core import DajaxiceConfig 6 | from dajaxice.core.Dajaxice import DajaxiceModule, DajaxiceFunction, Dajaxice 7 | from dajaxice.exceptions import FunctionNotCallableError 8 | 9 | 10 | class DajaxiceModuleTest(TestCase): 11 | 12 | def setUp(self): 13 | self.module = DajaxiceModule() 14 | 15 | def test_constructor(self): 16 | self.assertEqual(self.module.functions, {}) 17 | self.assertEqual(self.module.submodules, {}) 18 | 19 | def test_add_function(self): 20 | function = lambda x: x 21 | 22 | self.module.add('test', function) 23 | self.assertEqual(self.module.functions, {'test': function}) 24 | self.assertEqual(self.module.submodules, {}) 25 | 26 | self.module.add('foo.bar', function) 27 | self.assertEqual(self.module.functions, {'test': function}) 28 | self.assertEqual(self.module.submodules.keys(), ['foo']) 29 | self.assertEqual(self.module.submodules['foo'].functions, {'bar': function}) 30 | 31 | 32 | class DajaxiceFunctionTest(TestCase): 33 | 34 | def test_constructor(self): 35 | 36 | class CalledEception(Exception): 37 | pass 38 | 39 | def callback(): 40 | raise CalledEception 41 | 42 | function = DajaxiceFunction(callback, 'foo', 'POST') 43 | 44 | self.assertEqual(function.function, callback) 45 | self.assertEqual(function.name, 'foo') 46 | self.assertEqual(function.method, 'POST') 47 | self.assertRaises(CalledEception, function.call) 48 | 49 | 50 | class DajaxiceTest(TestCase): 51 | 52 | def setUp(self): 53 | self.dajaxice = Dajaxice() 54 | self.function = lambda x: x 55 | 56 | def test_constructor(self): 57 | self.assertEqual(self.dajaxice._registry, {}) 58 | 59 | def test_register(self): 60 | self.dajaxice.register(self.function, 'foo') 61 | self.assertTrue('foo' in self.dajaxice._registry) 62 | self.assertEqual(type(self.dajaxice._registry['foo']), DajaxiceFunction) 63 | 64 | def bar_function(): 65 | return 66 | 67 | self.dajaxice.register(bar_function) 68 | self.assertTrue('dajaxice.tests.bar_function' in self.dajaxice._registry) 69 | self.assertEqual(type(self.dajaxice._registry['dajaxice.tests.bar_function']), DajaxiceFunction) 70 | 71 | def test__is_callable(self): 72 | self.dajaxice.register(self.function, 'foo') 73 | self.dajaxice.register(self.function, 'bar', method='GET') 74 | 75 | self.assertTrue(self.dajaxice.is_callable('foo', 'POST')) 76 | self.assertTrue(self.dajaxice.is_callable('bar', 'GET')) 77 | self.assertFalse(self.dajaxice.is_callable('foo', 'GET')) 78 | self.assertFalse(self.dajaxice.is_callable('bar', 'POST')) 79 | self.assertFalse(self.dajaxice.is_callable('test', 'POST')) 80 | self.assertFalse(self.dajaxice.is_callable('test', 'GET')) 81 | 82 | def test_clean_method(self): 83 | self.assertEqual(self.dajaxice.clean_method('post'), 'POST') 84 | self.assertEqual(self.dajaxice.clean_method('get'), 'GET') 85 | self.assertEqual(self.dajaxice.clean_method('POST'), 'POST') 86 | self.assertEqual(self.dajaxice.clean_method('GET'), 'GET') 87 | self.assertEqual(self.dajaxice.clean_method('other'), 'POST') 88 | 89 | def test_modules(self): 90 | self.dajaxice.register(self.function, 'foo') 91 | self.dajaxice.register(self.function, 'bar') 92 | 93 | self.assertEqual(type(self.dajaxice.modules), DajaxiceModule) 94 | self.assertEqual(self.dajaxice.modules.functions.keys(), ['foo', 'bar']) 95 | 96 | 97 | class DajaxiceConfigTest(TestCase): 98 | 99 | def setUp(self): 100 | self.config = DajaxiceConfig() 101 | 102 | def test_defaults(self): 103 | self.assertTrue(self.config.DAJAXICE_XMLHTTPREQUEST_JS_IMPORT) 104 | self.assertTrue(self.config.DAJAXICE_JSON2_JS_IMPORT) 105 | self.assertEqual(self.config.DAJAXICE_EXCEPTION, 'DAJAXICE_EXCEPTION') 106 | self.assertEqual(self.config.DAJAXICE_MEDIA_PREFIX, 'dajaxice') 107 | 108 | dajaxice_url = r'^%s/' % self.config.DAJAXICE_MEDIA_PREFIX 109 | self.assertEqual(self.config.dajaxice_url, dajaxice_url) 110 | 111 | self.assertEqual(type(self.config.modules), DajaxiceModule) 112 | 113 | 114 | class DjangoIntegrationTest(TestCase): 115 | 116 | urls = 'dajaxice.tests.urls' 117 | 118 | def setUp(self): 119 | settings.INSTALLED_APPS += ('dajaxice.tests',) 120 | 121 | def test_calling_not_registered_function(self): 122 | self.failUnlessRaises(FunctionNotCallableError, self.client.post, '/dajaxice/dajaxice.tests.this_function_not_exist/') 123 | 124 | def test_calling_registered_function(self): 125 | response = self.client.post('/dajaxice/dajaxice.tests.test_foo/') 126 | 127 | self.failUnlessEqual(response.status_code, 200) 128 | self.failUnlessEqual(response.content, '{"foo": "bar"}') 129 | 130 | def test_calling_registered_function_with_params(self): 131 | 132 | response = self.client.post('/dajaxice/dajaxice.tests.test_foo_with_params/', {'argv': '{"param1":"value1"}'}) 133 | 134 | self.failUnlessEqual(response.status_code, 200) 135 | self.failUnlessEqual(response.content, '{"param1": "value1"}') 136 | 137 | def test_bad_function(self): 138 | 139 | response = self.client.post('/dajaxice/dajaxice.tests.test_ajax_exception/') 140 | self.failUnlessEqual(response.status_code, 200) 141 | self.failUnlessEqual(response.content, "DAJAXICE_EXCEPTION") 142 | 143 | def test_get_register(self): 144 | 145 | response = self.client.get('/dajaxice/dajaxice.tests.test_get_register/') 146 | 147 | self.failUnlessEqual(response.status_code, 200) 148 | self.failUnlessEqual(response.content, '{"foo": "user"}') 149 | 150 | def test_get_custom_name_register(self): 151 | 152 | response = self.client.get('/dajaxice/get_user_data/') 153 | 154 | self.failUnlessEqual(response.status_code, 200) 155 | self.failUnlessEqual(response.content, '{"bar": "user"}') 156 | 157 | def test_multi_register(self): 158 | 159 | response = self.client.get('/dajaxice/get_multi/') 160 | self.failUnlessEqual(response.status_code, 200) 161 | self.failUnlessEqual(response.content, '{"foo": "multi"}') 162 | 163 | response = self.client.post('/dajaxice/post_multi/') 164 | self.failUnlessEqual(response.status_code, 200) 165 | self.failUnlessEqual(response.content, '{"foo": "multi"}') 166 | -------------------------------------------------------------------------------- /dajaxice/tests/ajax.py: -------------------------------------------------------------------------------- 1 | import json 2 | from dajaxice.decorators import dajaxice_register 3 | 4 | 5 | @dajaxice_register 6 | def test_registered_function(request): 7 | return "" 8 | 9 | 10 | @dajaxice_register 11 | def test_string(request): 12 | return json.dumps({'string': 'hello world'}) 13 | 14 | 15 | @dajaxice_register 16 | def test_ajax_exception(request): 17 | raise Exception() 18 | 19 | 20 | @dajaxice_register 21 | def test_foo(request): 22 | return json.dumps({'foo': 'bar'}) 23 | 24 | 25 | @dajaxice_register 26 | def test_foo_with_params(request, param1): 27 | return json.dumps({'param1': param1}) 28 | 29 | 30 | @dajaxice_register(method='GET') 31 | def test_get_register(request): 32 | return json.dumps({'foo': 'user'}) 33 | 34 | 35 | @dajaxice_register(method='GET', name="get_user_data") 36 | def test_get_with_name_register(request): 37 | return json.dumps({'bar': 'user'}) 38 | 39 | 40 | @dajaxice_register(method='GET', name="get_multi") 41 | @dajaxice_register(name="post_multi") 42 | def test_multi_register(request): 43 | return json.dumps({'foo': 'multi'}) 44 | -------------------------------------------------------------------------------- /dajaxice/tests/requirements.txt: -------------------------------------------------------------------------------- 1 | Django 2 | -------------------------------------------------------------------------------- /dajaxice/tests/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | 3 | from dajaxice.core import dajaxice_autodiscover, dajaxice_config 4 | 5 | dajaxice_autodiscover() 6 | 7 | urlpatterns = patterns('', 8 | #Dajaxice URLS 9 | url(dajaxice_config.dajaxice_url, include('dajaxice.urls')), 10 | ) 11 | -------------------------------------------------------------------------------- /dajaxice/urls.py: -------------------------------------------------------------------------------- 1 | try: 2 | from django.conf.urls import patterns, url 3 | except ImportError: 4 | from django.conf.urls.defaults import patterns, url 5 | 6 | from .views import DajaxiceRequest 7 | 8 | urlpatterns = patterns('dajaxice.views', 9 | url(r'^(.+)/$', DajaxiceRequest.as_view(), name='dajaxice-call-endpoint'), 10 | url(r'', DajaxiceRequest.as_view(), name='dajaxice-endpoint'), 11 | ) 12 | -------------------------------------------------------------------------------- /dajaxice/utils.py: -------------------------------------------------------------------------------- 1 | from django.http import QueryDict 2 | 3 | 4 | def deserialize_form(data): 5 | """ 6 | Create a new QueryDict from a serialized form. 7 | """ 8 | return QueryDict(query_string=unicode(data).encode('utf-8')) 9 | -------------------------------------------------------------------------------- /dajaxice/views.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import django 3 | from django.conf import settings 4 | import json 5 | from django.views.generic.base import View 6 | from django.http import HttpResponse, Http404 7 | 8 | from dajaxice.exceptions import FunctionNotCallableError 9 | from dajaxice.core import dajaxice_functions, dajaxice_config 10 | 11 | log = logging.getLogger('dajaxice') 12 | 13 | 14 | def safe_dict(d): 15 | """ 16 | Recursively clone json structure with UTF-8 dictionary keys 17 | http://www.gossamer-threads.com/lists/python/bugs/684379 18 | """ 19 | if isinstance(d, dict): 20 | return dict([(k.encode('utf-8'), safe_dict(v)) for k, v in d.iteritems()]) 21 | elif isinstance(d, list): 22 | return [safe_dict(x) for x in d] 23 | else: 24 | return d 25 | 26 | 27 | class DajaxiceRequest(View): 28 | """ Handle all the dajaxice xhr requests. """ 29 | 30 | def dispatch(self, request, name=None): 31 | 32 | if not name: 33 | raise Http404 34 | 35 | # Check if the function is callable 36 | if dajaxice_functions.is_callable(name, request.method): 37 | 38 | function = dajaxice_functions.get(name) 39 | data = getattr(request, function.method).get('argv', '') 40 | 41 | # Clean the argv 42 | if data != 'undefined': 43 | try: 44 | data = safe_dict(json.loads(data)) 45 | except Exception: 46 | data = {} 47 | else: 48 | data = {} 49 | 50 | # Call the function. If something goes wrong, handle the Exception 51 | try: 52 | response = function.call(request, **data) 53 | except Exception: 54 | if settings.DEBUG: 55 | raise 56 | response = dajaxice_config.DAJAXICE_EXCEPTION 57 | if django.get_version() >= '1.7': 58 | return HttpResponse(response, content_type="application/x-json") 59 | else: 60 | return HttpResponse(response, mimetype="application/x-json") 61 | else: 62 | raise FunctionNotCallableError(name) 63 | -------------------------------------------------------------------------------- /example/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/example/1.png -------------------------------------------------------------------------------- /example/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/example/2.png -------------------------------------------------------------------------------- /example/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/example/3.png -------------------------------------------------------------------------------- /example/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/example/4.png -------------------------------------------------------------------------------- /example/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/example/5.png -------------------------------------------------------------------------------- /example/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/example/6.png -------------------------------------------------------------------------------- /giscube/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube/__init__.py -------------------------------------------------------------------------------- /giscube/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | #get the current directory 4 | current_dir = os.getcwd() 5 | 6 | STATIC_ROOT = '' 7 | STATIC_URL = '/static/' 8 | MEDIA_ROOT = '{0}/giscube_app/static/'.format(current_dir) 9 | MEDIA_URL = 'uploaded_files/' 10 | #BASE_DIR = '{0}/giscube_app/static/'.format(current_dir) #used for database -------------------------------------------------------------------------------- /giscube/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for giscube project. 3 | 4 | For more information on this file, see 5 | https://docs.djangoproject.com/en/1.6/topics/settings/ 6 | 7 | For the full list of settings and their values, see 8 | https://docs.djangoproject.com/en/1.6/ref/settings/ 9 | """ 10 | 11 | import os 12 | from config import STATIC_URL, MEDIA_ROOT, MEDIA_URL 13 | 14 | # SECURITY WARNING: keep the secret key used in production secret! 15 | SECRET_KEY = 'x(b%i4y0c*6ht(g=yo@4@@s%u06!h74_mt=i=-pt%s*yf9xc32' 16 | 17 | # SECURITY WARNING: don't run with debug turned on in production! 18 | DEBUG = True 19 | 20 | TEMPLATE_DEBUG = True 21 | 22 | ALLOWED_HOSTS = [] 23 | 24 | # Application definition 25 | INSTALLED_APPS = ( 26 | #'django.contrib.admin', 27 | #'django.contrib.auth', 28 | #'django.contrib.contenttypes', 29 | #'django.contrib.sessions', 30 | #'django.contrib.messages', 31 | 'django.contrib.staticfiles', 32 | 'giscube_app', 33 | 'dajaxice', 34 | ) 35 | 36 | MIDDLEWARE_CLASSES = ( 37 | 'django.contrib.sessions.middleware.SessionMiddleware', 38 | 'django.middleware.common.CommonMiddleware', 39 | 'django.middleware.csrf.CsrfViewMiddleware', 40 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 41 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 42 | 'django.contrib.messages.middleware.MessageMiddleware', 43 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 44 | ) 45 | 46 | TEMPLATE_LOADERS = ( 47 | 'django.template.loaders.filesystem.Loader', 48 | 'django.template.loaders.app_directories.Loader', 49 | 'django.template.loaders.eggs.Loader', 50 | ) 51 | 52 | TEMPLATE_CONTEXT_PROCESSORS = ( 53 | 'django.contrib.auth.context_processors.auth', 54 | 'django.core.context_processors.debug', 55 | 'django.core.context_processors.i18n', 56 | 'django.core.context_processors.media', 57 | 'django.core.context_processors.static', 58 | 'django.core.context_processors.request', 59 | 'django.contrib.messages.context_processors.messages' 60 | ) 61 | 62 | STATICFILES_FINDERS = ( 63 | 'django.contrib.staticfiles.finders.FileSystemFinder', 64 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 65 | 'dajaxice.finders.DajaxiceFinder', 66 | ) 67 | 68 | ROOT_URLCONF = 'giscube.urls' 69 | 70 | WSGI_APPLICATION = 'giscube.wsgi.application' 71 | 72 | LANGUAGE_CODE = 'en-us' 73 | 74 | TIME_ZONE = 'America/Los_Angeles' 75 | 76 | USE_I18N = True 77 | 78 | USE_L10N = True 79 | 80 | USE_TZ = True 81 | 82 | DATABASES = { 83 | 'default': { 84 | 'ENGINE': 'django.db.backends.sqlite3', 85 | 'NAME': os.path.join(MEDIA_ROOT, 'db.sqlite3'), 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /giscube/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | from django.conf import settings 3 | from django.conf.urls.static import static 4 | from django.contrib.staticfiles.urls import staticfiles_urlpatterns 5 | from dajaxice.core import dajaxice_autodiscover, dajaxice_config 6 | dajaxice_autodiscover() 7 | 8 | urlpatterns = patterns('', 9 | url(r'^', include('giscube_app.urls')), 10 | url(r''+dajaxice_config.dajaxice_url, include('dajaxice.urls')), 11 | ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 12 | 13 | urlpatterns += staticfiles_urlpatterns() -------------------------------------------------------------------------------- /giscube/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for giscube project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "giscube.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /giscube_app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/__init__.py -------------------------------------------------------------------------------- /giscube_app/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | class DocumentForm(forms.Form): 4 | docfile = forms.FileField( 5 | #label='Select a file', 6 | #help_text='max. 42 megabytes' 7 | ) 8 | -------------------------------------------------------------------------------- /giscube_app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from giscube.config import MEDIA_URL 3 | 4 | class Document(models.Model): 5 | docfile = models.FileField(upload_to=MEDIA_URL) -------------------------------------------------------------------------------- /giscube_app/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/scripts/__init__.py -------------------------------------------------------------------------------- /giscube_app/scripts/clip_geotiff_by_shp.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def clip_geotiff_by_shp(selected_geotiff, selected_shapefile, clipped_geotiff_name): 4 | string = "gdalwarp -cutline {0} -crop_to_cutline {1} {2}".format(selected_shapefile, selected_geotiff, clipped_geotiff_name) 5 | os.system(string) -------------------------------------------------------------------------------- /giscube_app/scripts/data_management.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def change_geotiff_resolution(selected_geotiff, geotiff_new_x_res, geotiff_new_y_res, geotiff_new_resolution_name): 5 | string = "gdalwarp -tr {0} {1} {2} {3}".format(geotiff_new_x_res, geotiff_new_y_res, selected_geotiff, geotiff_new_resolution_name) 6 | os.system(string) 7 | 8 | def color_table_on_geotiff(selected_geotiff, selected_color_table, colored_geotiff_name): 9 | string = 'gdaldem color-relief {0} {1} {2} -alpha -of GTiff'.format(selected_geotiff, selected_color_table, colored_geotiff_name) 10 | os.system(string) -------------------------------------------------------------------------------- /giscube_app/scripts/extract_shp_table.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | Project: Geothon (https://github.com/MBoustani/Geothon) 5 | File: Vector/export_shp_att_csv.py 6 | Description: This code exports Shapefile attribute table to csv file 7 | Author: Maziyar Boustani (github.com/MBoustani) 8 | ''' 9 | import csv 10 | 11 | try: 12 | import ogr 13 | except ImportError: 14 | from osgeo import ogr 15 | 16 | def extract_shp_table(shp_file_name, csv_file_name): 17 | #set the driver to ESRI Shapefiel 18 | driver = ogr.GetDriverByName('ESRI Shapefile') 19 | 20 | #open shapefile 21 | shp_datasource = driver.Open(shp_file_name) 22 | 23 | #get shapefile layer 24 | layer = shp_datasource.GetLayerByIndex(0) 25 | 26 | #get shapefile layer definition 27 | layer_defn = layer.GetLayerDefn() 28 | 29 | #get number of fields(columns) from shapefile attribute table 30 | num_field_col = layer_defn.GetFieldCount() 31 | 32 | #create csv file to store shapefile attribute table 33 | with open(csv_file_name, 'wb') as csv_file: 34 | writer = csv.writer(csv_file) 35 | #store field header 36 | field_name = [] 37 | for field in range(num_field_col): 38 | field_name.append(layer_defn.GetFieldDefn(field).GetName()) 39 | writer.writerow(field_name) 40 | 41 | #store attribute from each feature 42 | num_feature = layer.GetFeatureCount() 43 | for each in range(num_feature): 44 | feautre = layer.GetFeature(each) 45 | feautre_name = [] 46 | for i in range(num_field_col): 47 | feautre_name.append(feautre.GetFieldAsString(i)) 48 | writer.writerow(feautre_name) -------------------------------------------------------------------------------- /giscube_app/scripts/gtif_to_tile.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | from giscube.config import MEDIA_ROOT, MEDIA_URL 4 | import subprocess 5 | 6 | def create_gtif(gtif): 7 | UPLOADED_FILE_DIR = '{0}{1}'.format(MEDIA_ROOT, MEDIA_URL) 8 | gtif_path = UPLOADED_FILE_DIR + gtif 9 | gtif_folder = gtif.split(".tif")[0] 10 | string = "gdal2tiles.py {0} {1}".format(gtif_path, gtif_folder) 11 | subprocess.Popen(["gdal2tiles.py","{0}".format(gtif_path),"{0}".format(gtif_folder)]) 12 | 13 | return gtif_folder -------------------------------------------------------------------------------- /giscube_app/scripts/metadata.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | try: 4 | from osgeo import gdal 5 | from osgeo import osr 6 | except ImportError: 7 | import gdal 8 | import osr 9 | try: 10 | from osgeo import ogr 11 | except ImportError: 12 | import ogr 13 | 14 | from netCDF4 import Dataset 15 | import numpy as np 16 | import urllib2 17 | import json 18 | 19 | def get_nc_data(nc_file, latitude_var, longitude_var, time_var, value_var, selected_time_index): 20 | print nc_file 21 | nc_dataset = open_file(nc_file) 22 | if nc_dataset: 23 | lat = nc_dataset.variables[latitude_var] 24 | lon = nc_dataset.variables[longitude_var] 25 | time = nc_dataset.variables[time_var] 26 | value = nc_dataset.variables[value_var] 27 | 28 | lat_dim = lat.dimensions 29 | lon_dim = lon.dimensions 30 | time_dim = time.dimensions 31 | value_dim = value.dimensions 32 | 33 | lat_shape = lat.shape 34 | lon_shape = lon.shape 35 | time_shape = time.shape 36 | value_shape = value.shape 37 | 38 | print 'Latitude shape: {0}'.format(lat_shape) 39 | print 'Longitude shape: {0}'.format(lon_shape) 40 | print 'Time shape: {0}'.format(time_shape) 41 | print 'Value shape: {0}'.format(value_shape) 42 | 43 | print "Getting dimensions info" 44 | dims_info = {} 45 | for i, each in enumerate(lat_dim): 46 | dims_info[each] = lat_shape[i] 47 | 48 | for i, each in enumerate(lon_dim): 49 | dims_info[each] = lon_shape[i] 50 | 51 | for i, each in enumerate(time_dim): 52 | dims_info[each] = time_shape[i] 53 | 54 | print "Slicing vlaues" 55 | slices = () 56 | for dim in value_dim: 57 | if dim in dims_info: 58 | if dim in time_dim: 59 | slices += (slice(selected_time_index,selected_time_index+1),) 60 | else: 61 | slices += (slice(0,dims_info[dim]+1),) 62 | else: 63 | slices += (slice(0,1),) 64 | print "Values sliced" 65 | print np.squeeze(value[slices]).shape 66 | return np.squeeze(value[slices]) 67 | 68 | def open_file(file_path): 69 | try: 70 | nc_file = Dataset(file_path, mode='r') 71 | if not nc_file: 72 | raise "File cannot be opened" 73 | return nc_file 74 | except: 75 | raise "File cannot be opened" 76 | sys.exit() 77 | 78 | def get_variables(nc_file): 79 | if nc_file: 80 | return [variable.encode() for variable in nc_file.variables.keys()] 81 | 82 | 83 | def get_file_name(file_path): 84 | if file_path: 85 | return file_path 86 | 87 | 88 | def variables_info(nc_file, all_variables): 89 | variables_info = [] 90 | for value in all_variables: 91 | variable = nc_file.variables[value] 92 | each_variable = {} 93 | each_variable[value] = {} 94 | each_variable[value]['dimensions'] = variable.dimensions 95 | for att in variable.ncattrs(): 96 | each_variable[value][att] = variable.getncattr(att) 97 | variables_info.append(each_variable) 98 | 99 | return variables_info 100 | 101 | 102 | def get_nc_metadata(file_path): 103 | try: 104 | nc_metadata = urllib2.urlopen("http://127.0.0.1:18080/uploaded_files/{0}/?output=json&traverse".format(file_path)).read() 105 | dic = json.loads(nc_metadata) 106 | nc_variables = [] 107 | for each in dic['leaves']: 108 | nc_variables.append(each['name']) 109 | return {'file_name':file_path, 'nc_metadata':nc_metadata, 'nc_variables':nc_variables} 110 | except: 111 | return None 112 | 113 | 114 | def get_hdf_metadata(file_path): 115 | try: 116 | hdf_metadata = urllib2.urlopen("http://127.0.0.1:18080/uploaded_files/{0}/?output=json&traverse".format(file_path)).read() 117 | return {'file_name':file_path, 'hdf_metadata':hdf_metadata} 118 | except: 119 | return None 120 | 121 | #####shp_name_info.py 122 | 123 | def open_shp_file(file_path): 124 | try: 125 | vector_file = ogr.Open(file_path) 126 | if not vector_file: 127 | raise "File cannot be opened" 128 | return vector_file 129 | except: 130 | raise "File cannot be opened" 131 | sys.exit() 132 | 133 | def get_shp_name(vector_file): 134 | try: 135 | file_name = vector_file.GetName() 136 | return file_name 137 | except: 138 | return None 139 | 140 | def get_shp_format(vector_file): 141 | try: 142 | file_format = vector_file.GetDriver().GetName() 143 | return file_format 144 | except: 145 | return None 146 | 147 | def get_shp_number_of_layers(vector_file): 148 | try: 149 | number_of_layers = vector_file.GetLayerCount() 150 | return number_of_layers 151 | except: 152 | return None 153 | 154 | def get_shp_layer(vector_file, layer_index): 155 | try: 156 | layer = vector_file.GetLayerByIndex(layer_index) 157 | return layer 158 | except: 159 | return None 160 | 161 | def get_shp_layer_name(layer_file): 162 | try: 163 | layer_name = layer_file.GetName() 164 | return layer_name 165 | except: 166 | return None 167 | 168 | def get_shp_number_of_feature(layer_file): 169 | try: 170 | number_of_feature = layer_file.GetFeatureCount() 171 | return number_of_feature 172 | except: 173 | return None 174 | 175 | def get_shp_layer_type(layer_file): 176 | try: 177 | geom_type_index = layer_file.GetLayerDefn().GetGeomType() 178 | layer_type = ogr.GeometryTypeToName(geom_type_index) 179 | return layer_type 180 | except: 181 | return None 182 | 183 | def get_shp_layer_spatial_reference(layer_file): 184 | try: 185 | layer_spatial_reference = layer_file.GetSpatialRef().ExportToPrettyWkt() 186 | return layer_spatial_reference 187 | except: 188 | return None 189 | 190 | def get_shp_layer_extend(layer_file): 191 | try: 192 | layer_extend = layer_file.GetExtent() 193 | return layer_extend 194 | except: 195 | return None 196 | 197 | 198 | def run_shp_info(file_path): 199 | layers = [] 200 | vector_file = open_shp_file(file_path) #To open vector file 201 | file_name = get_shp_name(vector_file) #To print file name 202 | file_format = get_shp_format(vector_file) #To print file format 203 | file_number_of_layers = get_shp_number_of_layers(vector_file) #To print number of layer/s 204 | for layer_index in range(file_number_of_layers): 205 | layer = {} 206 | layer_file = get_shp_layer(vector_file, layer_index) 207 | layer['layer file'] = layer_file 208 | layer_name = get_shp_layer_name(layer_file) 209 | layer['layer name'] = layer_name 210 | number_of_feature = get_shp_number_of_feature(layer_file) 211 | layer['number of feature'] = number_of_feature 212 | layer_type = get_shp_layer_type(layer_file) 213 | layer['layer type'] = layer_type 214 | layer_spatial_reference = get_shp_layer_spatial_reference(layer_file) 215 | layer['layer spatial reference'] = layer_spatial_reference 216 | layer_extend = get_shp_layer_extend(layer_file) 217 | layer['layer extend'] = layer_extend 218 | layers.append(layer) 219 | 220 | return {'file_name':file_name, 'file_format':file_format , 'num_layer':str(file_number_of_layers),\ 221 | 'layer_name':layer['layer name'], 'number_of_feature':layer['number of feature'],\ 222 | 'layer_type':layer['layer type'], 'layer_spatial_reference':layer['layer spatial reference'],\ 223 | 'layer_extend':layer['layer extend']} 224 | 225 | 226 | 227 | #####tif_name_info.py 228 | 229 | def open_tif(file_path): 230 | try: 231 | raster_file = gdal.Open(file_path) 232 | if not raster_file: 233 | raise "File cannot be opened" 234 | return raster_file 235 | except: 236 | raise "File cannot be opened" 237 | sys.exit() 238 | 239 | def get_tif_name(raster_file): 240 | try: 241 | file_name = raster_file.GetDescription() 242 | return file_name 243 | except: 244 | return None 245 | 246 | def get_tif_format(raster_file): 247 | try: 248 | file_format = raster_file.GetDriver().LongName 249 | return file_format 250 | except: 251 | return None 252 | 253 | def get_raster_number_of_band(raster_file): 254 | try: 255 | raster_number_of_band = raster_file.RasterCount 256 | return raster_number_of_band 257 | except: 258 | return None 259 | 260 | def get_raster_x_y_size(raster_file): 261 | try: 262 | raster_x_y_size = [raster_file.RasterXSize, raster_file.RasterYSize] 263 | return raster_x_y_size 264 | except: 265 | return None 266 | 267 | def get_raster_projection(raster_file): 268 | try: 269 | raster_projection = raster_file.GetProjectionRef() 270 | hSRS = osr.SpatialReference() 271 | hSRS.ImportFromWkt(raster_projection ) 272 | pszPrettyWkt = hSRS.ExportToPrettyWkt(False) 273 | return pszPrettyWkt 274 | except: 275 | return None 276 | 277 | def get_raster_geotransform(raster_file): 278 | try: 279 | raster_geotransform = raster_file.GetGeoTransform() 280 | return raster_geotransform 281 | except: 282 | return None 283 | 284 | def get_raster_origin(raster_geotransform): 285 | try: 286 | raster_origin = (raster_geotransform[0], raster_geotransform[3]) 287 | return raster_origin 288 | except Exception: 289 | return None 290 | 291 | def get_raster_pixle_size(raster_geotransform): 292 | try: 293 | raster_pixle_size = (raster_geotransform[1], raster_geotransform[5]) 294 | return raster_pixle_size 295 | except: 296 | return None 297 | 298 | 299 | 300 | def run_tif_info(file_path): 301 | layers = [] 302 | raster_file = open_tif(file_path) #To open raster file 303 | file_name = get_tif_name(raster_file) #To print file name 304 | file_format = get_tif_format(raster_file) #To print file format 305 | raster_number_of_band = get_raster_number_of_band(raster_file) 306 | raster_x_y_size = get_raster_x_y_size(raster_file) 307 | raster_projection = get_raster_projection(raster_file) 308 | raster_geotransform = get_raster_geotransform(raster_file) 309 | raster_origin = get_raster_origin(raster_geotransform) 310 | raster_pixle_size = get_raster_pixle_size(raster_geotransform) 311 | 312 | return {'file_name':file_name, 'file_format':file_format , 'num_band':str(raster_number_of_band),\ 313 | 'raster_x_y_size':raster_x_y_size, 'raster_projection':raster_projection,\ 314 | 'raster_geotransform':raster_geotransform, 'raster_origin':raster_origin,\ 315 | 'raster_pixle_size':raster_pixle_size} -------------------------------------------------------------------------------- /giscube_app/scripts/open_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | try: 4 | from osgeo import ogr 5 | except ImportError: 6 | import ogr 7 | 8 | try: 9 | from osgeo import gdal 10 | from osgeo import osr 11 | except ImportError: 12 | import gdal 13 | import osr 14 | 15 | 16 | def open_shp_file(file_path): 17 | try: 18 | vector_file = ogr.Open(file_path) 19 | return vector_file 20 | except: 21 | return False 22 | 23 | 24 | def open_tif_file(file_path): 25 | try: 26 | raster_file = gdal.Open(file_path) 27 | return raster_file 28 | except: 29 | return False -------------------------------------------------------------------------------- /giscube_app/scripts/opendap.py: -------------------------------------------------------------------------------- 1 | from pydap.client import open_url 2 | from netcdftime import utime 3 | import numpy as np 4 | import urllib 5 | 6 | from giscube.config import MEDIA_ROOT, MEDIA_URL 7 | 8 | def opendap_metadata(opendap_url): 9 | response = urllib.urlopen(opendap_url + ".das") 10 | return response.read() 11 | 12 | def load(url, frm, name): 13 | if url.split(".")[-1] != "gz": 14 | url = url + "gz" 15 | if frm == "ASCII": 16 | urllib.urlretrieve ("{0}.ascii".format(url), "{0}{1}".format(MEDIA_ROOT + MEDIA_URL, "{0}.ascii".format(name))) 17 | elif frm == "nc3": 18 | urllib.urlretrieve ("{0}.nc".format(url), "{0}{1}".format(MEDIA_ROOT + MEDIA_URL, "{0}.nc".format(name))) 19 | elif frm == "nc4": 20 | urllib.urlretrieve ("{0}.dap.nc4".format(url), "{0}{1}".format(MEDIA_ROOT + MEDIA_URL, "{0}.nc".format(name))) -------------------------------------------------------------------------------- /giscube_app/scripts/spatial_analysis.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | try: 4 | import ogr 5 | except ImportError: 6 | from osgeo import ogr 7 | 8 | try: 9 | import osr 10 | except ImportError: 11 | from osgeo import osr 12 | 13 | 14 | def buffer_shapefile(selected_shp, buffer_shp_buffer_range, buffer_shp_out_name, buffer_shp_out_layername): 15 | if selected_shp.split(".")[-1] != "shp": 16 | selected_shp = selected_shp + ".shp" 17 | try: 18 | buffer_shp_buffer_range = float(buffer_shp_buffer_range) 19 | driver = ogr.GetDriverByName('ESRI Shapefile') 20 | in_shp_datasource = driver.Open(selected_shp) 21 | in_layer = in_shp_datasource.GetLayer() 22 | in_srs = in_layer.GetSpatialRef() 23 | num_feature = in_layer.GetFeatureCount() 24 | out_shp_datasource = driver.CreateDataSource(buffer_shp_out_name) 25 | srs = osr.SpatialReference() 26 | srs.ImportFromEPSG(4326) 27 | print in_srs 28 | print srs 29 | out_layer = out_shp_datasource.CreateLayer(buffer_shp_out_layername, in_srs, ogr.wkbMultiPolygon) 30 | for each in range(num_feature): 31 | in_feature = in_layer.GetFeature(each) 32 | in_geom = in_feature.GetGeometryRef() 33 | bufer_geom = in_geom.Buffer(buffer_shp_buffer_range) 34 | out_feature = ogr.Feature(out_layer.GetLayerDefn()) 35 | out_feature.SetGeometry(bufer_geom) 36 | out_layer.CreateFeature(out_feature) 37 | return "Done." 38 | except: 39 | return "Someting went wrong" 40 | 41 | 42 | def find_point_inside_feature(selected_vector, point_inside_shapefile_lat, point_inside_shapefile_lon): 43 | 44 | in_shp_datasource = ogr.Open("{0}.shp".format(selected_vector)) 45 | in_layer = in_shp_datasource.GetLayerByIndex(0) 46 | in_layer_defn = in_layer.GetLayerDefn() 47 | num_field_col = in_layer_defn.GetFieldCount() 48 | 49 | try: 50 | point = ogr.Geometry(ogr.wkbPoint) 51 | point.AddPoint(float(point_inside_shapefile_lon), float(point_inside_shapefile_lat)) 52 | except: 53 | print "cannot create point geometry" 54 | 55 | try: 56 | field_name = [] 57 | for field in range(num_field_col): 58 | field_name.append(in_layer_defn.GetFieldDefn(field).GetName()) 59 | except: 60 | print "Cannot read feature attribute information" 61 | 62 | feature_info = "Point is not in any feature." 63 | features_number = in_layer.GetFeatureCount() 64 | for i in range(features_number): 65 | in_shp_feature = in_layer.GetFeature(i) 66 | in_feature_geometry = in_shp_feature.GetGeometryRef() 67 | if point.Within(in_feature_geometry): 68 | field_count = in_shp_feature.GetFieldCount() 69 | feature_info = "" 70 | for field in range(field_count): 71 | feature_info += "
{1}
".format(field_name[field], in_shp_feature.GetFieldAsString(field)) 72 | break 73 | 74 | return feature_info 75 | -------------------------------------------------------------------------------- /giscube_app/scripts/what_file.py: -------------------------------------------------------------------------------- 1 | try: 2 | from osgeo import gdal 3 | from osgeo import ogr 4 | except ImportError: 5 | import gdal 6 | import ogr 7 | 8 | from gdalconst import GA_ReadOnly 9 | 10 | 11 | 12 | def what_format(file_path): 13 | ''' 14 | Open either raster or vector file and return format of it 15 | ''' 16 | try: 17 | dataset = gdal.Open(file_path, GA_ReadOnly) 18 | driver_name = dataset.GetDriver().LongName 19 | return driver_name 20 | except: 21 | driver_name = "Format not found." 22 | 23 | try: 24 | dataset = ogr.Open(file_path) 25 | driver_name = dataset.GetDriver().GetName() 26 | print driver_name 27 | return driver_name 28 | except: 29 | driver_name = "Format not found." 30 | 31 | return driver_name -------------------------------------------------------------------------------- /giscube_app/static/css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/css/.DS_Store -------------------------------------------------------------------------------- /giscube_app/static/css/bootstrap-glyphicons.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphiconshalflings-regular.eot');src:url('../fonts/glyphiconshalflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphiconshalflings-regular.woff') format('woff'),url('../fonts/glyphiconshalflings-regular.ttf') format('truetype'),url('../fonts/glyphiconshalflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon:before{font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-plus:before{content:"\002b"}.glyphicon-minus:before{content:"\2212"}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse:before{content:"\e159"}.glyphicon-collapse-top:before{content:"\e160"} 2 | /* This beautiful CSS-File has been crafted with LESS (lesscss.org) and compiled by simpLESS (wearekiss.com/simpless) */ -------------------------------------------------------------------------------- /giscube_app/static/css/jquery.fileupload-ui.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload UI Plugin CSS 8.8.5 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2010, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | .fileupload-buttonbar .btn, 14 | .fileupload-buttonbar .toggle { 15 | margin-bottom: 5px; 16 | } 17 | .progress-animated .progress-bar, 18 | .progress-animated .bar { 19 | background: url("../img/progressbar.gif") !important; 20 | filter: none; 21 | } 22 | .fileupload-loading { 23 | float: right; 24 | width: 32px; 25 | height: 32px; 26 | background: url("../img/loading.gif") center no-repeat; 27 | background-size: contain; 28 | display: none; 29 | } 30 | .fileupload-processing .fileupload-loading { 31 | display: block; 32 | } 33 | .files audio, 34 | .files video { 35 | max-width: 300px; 36 | } 37 | 38 | @media (max-width: 767px) { 39 | .fileupload-buttonbar .toggle, 40 | .files .toggle, 41 | .files .btn span { 42 | display: none; 43 | } 44 | .files .name { 45 | width: 80px; 46 | word-wrap: break-word; 47 | } 48 | .files audio, 49 | .files video { 50 | max-width: 80px; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /giscube_app/static/css/jquery.fileupload.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload Plugin CSS 1.3.0 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2013, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | .fileinput-button { 14 | position: relative; 15 | overflow: hidden; 16 | } 17 | .fileinput-button input { 18 | position: absolute; 19 | top: 0; 20 | right: 0; 21 | margin: 0; 22 | opacity: 0; 23 | -ms-filter: 'alpha(opacity=0)'; 24 | font-size: 200px; 25 | direction: ltr; 26 | cursor: pointer; 27 | } 28 | 29 | /* Fixes for IE < 8 */ 30 | @media screen\9 { 31 | .fileinput-button input { 32 | filter: alpha(opacity=0); 33 | font-size: 100%; 34 | height: 100%; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /giscube_app/static/css/leaflet-0.6.4_leaflet.ie.css: -------------------------------------------------------------------------------- 1 | .leaflet-vml-shape { 2 | width: 1px; 3 | height: 1px; 4 | } 5 | .lvml { 6 | behavior: url(#default#VML); 7 | display: inline-block; 8 | position: absolute; 9 | } 10 | 11 | .leaflet-control { 12 | display: inline; 13 | } 14 | 15 | .leaflet-popup-tip { 16 | width: 21px; 17 | _width: 27px; 18 | margin: 0 auto; 19 | _margin-top: -3px; 20 | 21 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 22 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; 23 | } 24 | .leaflet-popup-tip-container { 25 | margin-top: -1px; 26 | } 27 | .leaflet-popup-content-wrapper, .leaflet-popup-tip { 28 | border: 1px solid #999; 29 | } 30 | .leaflet-popup-content-wrapper { 31 | zoom: 1; 32 | } 33 | 34 | .leaflet-control-zoom, 35 | .leaflet-control-layers { 36 | border: 3px solid #999; 37 | } 38 | .leaflet-control-layers-toggle { 39 | } 40 | .leaflet-control-attribution, 41 | .leaflet-control-layers, 42 | .leaflet-control-scale-line { 43 | background: white; 44 | } 45 | .leaflet-zoom-box { 46 | filter: alpha(opacity=50); 47 | } 48 | .leaflet-control-attribution { 49 | border-top: 1px solid #bbb; 50 | border-left: 1px solid #bbb; 51 | } -------------------------------------------------------------------------------- /giscube_app/static/css/ol.css: -------------------------------------------------------------------------------- 1 | .ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:#95b9e6;background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;padding:0 2px}.ol-unsupported{display:none}.ol-viewport .ol-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ol-control{position:absolute;background-color:#eee;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px}.ol-control:hover{background-color:rgba(255,255,255,.6)}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}@media print{.ol-control{display:none}}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-size:1.14em;font-weight:700;text-decoration:none;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:#7b98bc;background-color:rgba(0,60,136,.5);border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-family:Arial;font-weight:400;font-size:1.2em}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:focus,.ol-control button:hover{text-decoration:none;background-color:#4c6079;background-color:rgba(0,60,136,.7)}.ol-zoom-extent button:after{content:"E"}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}button.ol-full-screen-false:after{content:"\2194"}button.ol-full-screen-true:after{content:"\00d7"}.ol-has-tooltip [role=tooltip]{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden;font-weight:400;font-size:14px;text-shadow:0 0 2px #fff}.ol-has-tooltip:focus [role=tooltip],.ol-has-tooltip:hover [role=tooltip]{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;clip:auto;padding:0 .4em;font-size:.8em;height:1.2em;width:auto;line-height:1.2em;z-index:1100;max-height:100px;white-space:nowrap;display:inline-block;background:#FFF;background:rgba(255,255,255,.6);color:#000;border:3px solid transparent;border-left-width:0;border-radius:0 4px 4px 0;bottom:.3em;left:2.2em}.ol-touch .ol-has-tooltip:focus [role=tooltip],.ol-touch .ol-has-tooltip:hover [role=tooltip]{display:none}.ol-zoom .ol-has-tooltip:focus [role=tooltip],.ol-zoom .ol-has-tooltip:hover [role=tooltip]{top:1.1em}.ol-attribution .ol-has-tooltip:focus [role=tooltip],.ol-attribution .ol-has-tooltip:hover [role=tooltip],.ol-full-screen .ol-has-tooltip:focus [role=tooltip],.ol-full-screen .ol-has-tooltip:hover [role=tooltip],.ol-rotate .ol-has-tooltip:focus [role=tooltip],.ol-rotate .ol-has-tooltip:hover [role=tooltip]{right:2.2em;left:auto;border-radius:4px 0 0 4px;border-left-width:3px;border-right-width:0}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em)}.ol-attribution ul{margin:0;padding:0 .5em;font-size:.7rem;line-height:1.375em;color:#000;text-shadow:0 0 2px #fff;max-width:calc(100% - 3.6em)}.ol-attribution li{display:inline;list-style:none;line-height:inherit}.ol-attribution li:not(:last-child):after{content:" "}.ol-attribution img{max-height:2em}.ol-attribution button,.ol-attribution ul{display:inline-block}.ol-attribution.ol-collapsed ul,.ol-attribution:not(.ol-collapsed) button:hover [role=tooltip]{display:none}.ol-attribution.ol-logo-only ul{display:block}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0;height:1.1em;line-height:1em}.ol-attribution.ol-logo-only{background:0 0;bottom:.4em;height:1.1em;line-height:1em}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-logo-only button,.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{position:absolute;top:4.5em;left:.5em;background:#eee;background:rgba(255,255,255,.4);border-radius:4px;outline:0;overflow:hidden;width:1.5675em;height:200px;padding:3px;margin:0}.ol-zoomslider-thumb{position:absolute;display:block;background:#7b98bc;background:rgba(0,60,136,.5);border-radius:2px;outline:0;overflow:hidden;cursor:pointer;font-size:1.14em;height:1em;width:1.375em;margin:3px;padding:0}.ol-touch .ol-zoomslider{top:5.5em;width:2.052em}.ol-touch .ol-zoomslider-thumb{width:1.8em}.ol-attribution,.ol-control button,.ol-has-tooltip [role=tooltip],.ol-scale-line-inner{font-family:'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif} -------------------------------------------------------------------------------- /giscube_app/static/css/side_menu.css: -------------------------------------------------------------------------------- 1 | .menu { 2 | width: 40%; 3 | height: 100%; 4 | position: fixed; 5 | background-color: #fff; 6 | -webkit-transition: all 1s; 7 | transition: all 1s; 8 | right: 0; 9 | overflow-y: auto; 10 | padding-bottom: 0px; 11 | z-index: 10; 12 | } 13 | 14 | .menu.closed { right: -40%; } 15 | 16 | #toggle { 17 | background-color: #000000; 18 | height: 100%; 19 | min-height: 100%; 20 | width: 0px; 21 | position: fixed; 22 | top: 0; 23 | bottom: 0; 24 | -webkit-transition: all .7s ease; 25 | transition: all .7s ease; 26 | } 27 | 28 | #toggle.closed { 29 | right:0px; 30 | top: 0; 31 | bottom: 0; 32 | left: 0; 33 | width: 60%; 34 | height: 100%; 35 | opacity: .9; 36 | z-index: 5; 37 | } -------------------------------------------------------------------------------- /giscube_app/static/css/style.css: -------------------------------------------------------------------------------- 1 | body{width: 99%; padding-top: 3px; padding-bottom: 3px;} 2 | #logo{box-shadow: 3px 0px 4px #939393; width: 100%;} 3 | #map-container{max-width: none; height: 100%;} 4 | #map{box-shadow: 0px 0px 5px 4px #939393; width: 100%; height: 90%; margin-top: 10px;} 5 | #side_menu{background: #2f2f2f; height: 100%; box-shadow: 3px 0px 4px #939393; position: fixed; margin-top: 5.5%;} 6 | #github{width: 2%; position:fixed; bottom:0;} 7 | #uploaded_files{border-left: 1px groove #c4c2c5; height: 100%;} 8 | .red{color: #ff0600; opacity: 1;} 9 | .right{float: right} 10 | .tree { 11 | min-height:20px; 12 | padding:19px; 13 | margin-bottom:20px; 14 | -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05); 15 | -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05); 16 | box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05) 17 | } 18 | .tree li { 19 | list-style-type:none; 20 | margin:0; 21 | padding:10px 5px 0 5px; 22 | position:relative 23 | } 24 | .tree li::before, .tree li::after { 25 | content:''; 26 | left:-20px; 27 | position:absolute; 28 | right:auto 29 | } 30 | .tree li::before { 31 | border-left:1px solid #999; 32 | bottom:50px; 33 | height:100%; 34 | top:0; 35 | width:1px 36 | } 37 | .tree li::after { 38 | border-top:1px solid #999; 39 | height:20px; 40 | top:25px; 41 | width:25px 42 | } 43 | .tree li span { 44 | cursor:pointer; 45 | -moz-border-radius:0px; 46 | -webkit-border-radius:0px; 47 | border:1px solid #999; 48 | border-radius:0px; 49 | display:inline-block; 50 | padding:3px 8px; 51 | text-decoration:none 52 | } 53 | .tree li.parent_li>span { 54 | cursor:pointer 55 | } 56 | .tree>ul>li::before, .tree>ul>li::after { 57 | border:0 58 | } 59 | .tree li:last-child::before { 60 | height:30px 61 | } 62 | .tree li.parent_li>span:hover, .tree li.parent_li>span:hover+ul li span { 63 | background:#eee; 64 | border:1px solid #94a0b4; 65 | color:#000 66 | } 67 | #tools_title{font-size: 30px; color: #31a467; font-weight: 100;} 68 | #tools_subtitle{font-size: 20px; color: #b6af32; font-weight: 100;} 69 | #tool_title{font-size: 15px; color: #4f4d50; font-weight: 200;} -------------------------------------------------------------------------------- /giscube_app/static/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/db.sqlite3 -------------------------------------------------------------------------------- /giscube_app/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /giscube_app/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /giscube_app/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /giscube_app/static/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/img/.DS_Store -------------------------------------------------------------------------------- /giscube_app/static/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/img/github.png -------------------------------------------------------------------------------- /giscube_app/static/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /giscube_app/static/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /giscube_app/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/img/logo.png -------------------------------------------------------------------------------- /giscube_app/static/img/logo_beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/img/logo_beta.png -------------------------------------------------------------------------------- /giscube_app/static/js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MBoustani/GISCube/dabb59c5977f97fb427afc4cdcd9b1a921784734/giscube_app/static/js/.DS_Store -------------------------------------------------------------------------------- /giscube_app/static/js/KML.js: -------------------------------------------------------------------------------- 1 | /*global L: true */ 2 | 3 | L.KML = L.FeatureGroup.extend({ 4 | options: { 5 | async: true 6 | }, 7 | 8 | initialize: function(kml, options) { 9 | L.Util.setOptions(this, options); 10 | this._kml = kml; 11 | this._layers = {}; 12 | 13 | if (kml) { 14 | this.addKML(kml, options, this.options.async); 15 | } 16 | }, 17 | 18 | loadXML: function(url, cb, options, async) { 19 | if (async == undefined) async = this.options.async; 20 | if (options == undefined) options = this.options; 21 | 22 | var req = new window.XMLHttpRequest(); 23 | req.open('GET', url, async); 24 | try { 25 | req.overrideMimeType('text/xml'); // unsupported by IE 26 | } catch(e) {} 27 | req.onreadystatechange = function() { 28 | if (req.readyState != 4) return; 29 | if(req.status == 200) cb(req.responseXML, options); 30 | }; 31 | req.send(null); 32 | }, 33 | 34 | addKML: function(url, options, async) { 35 | var _this = this; 36 | var cb = function(gpx, options) { _this._addKML(gpx, options) }; 37 | this.loadXML(url, cb, options, async); 38 | }, 39 | 40 | _addKML: function(xml, options) { 41 | var layers = L.KML.parseKML(xml); 42 | if (!layers || !layers.length) return; 43 | for (var i = 0; i < layers.length; i++) 44 | { 45 | this.fire('addlayer', { 46 | layer: layers[i] 47 | }); 48 | this.addLayer(layers[i]); 49 | } 50 | this.latLngs = L.KML.getLatLngs(xml); 51 | this.fire("loaded"); 52 | }, 53 | 54 | latLngs: [] 55 | }); 56 | 57 | L.Util.extend(L.KML, { 58 | 59 | parseKML: function (xml) { 60 | var style = this.parseStyle(xml); 61 | this.parseStyleMap(xml, style); 62 | var el = xml.getElementsByTagName("Folder"); 63 | var layers = [], l; 64 | for (var i = 0; i < el.length; i++) { 65 | if (!this._check_folder(el[i])) { continue; } 66 | l = this.parseFolder(el[i], style); 67 | if (l) { layers.push(l); } 68 | } 69 | el = xml.getElementsByTagName('Placemark'); 70 | for (var j = 0; j < el.length; j++) { 71 | if (!this._check_folder(el[j])) { continue; } 72 | l = this.parsePlacemark(el[j], xml, style); 73 | if (l) { layers.push(l); } 74 | } 75 | return layers; 76 | }, 77 | 78 | // Return false if e's first parent Folder is not [folder] 79 | // - returns true if no parent Folders 80 | _check_folder: function (e, folder) { 81 | e = e.parentElement; 82 | while (e && e.tagName !== "Folder") 83 | { 84 | e = e.parentElement; 85 | } 86 | return !e || e === folder; 87 | }, 88 | 89 | parseStyle: function (xml) { 90 | var style = {}; 91 | var sl = xml.getElementsByTagName("Style"); 92 | 93 | //for (var i = 0; i < sl.length; i++) { 94 | var attributes = {color: true, width: true, Icon: true, href: true, 95 | hotSpot: true}; 96 | 97 | function _parse(xml) { 98 | var options = {}; 99 | for (var i = 0; i < xml.childNodes.length; i++) { 100 | var e = xml.childNodes[i]; 101 | var key = e.tagName; 102 | if (!attributes[key]) { continue; } 103 | if (key === 'hotSpot') 104 | { 105 | for (var j = 0; j < e.attributes.length; j++) { 106 | options[e.attributes[j].name] = e.attributes[j].nodeValue; 107 | } 108 | } else { 109 | var value = e.childNodes[0].nodeValue; 110 | if (key === 'color') { 111 | options.opacity = parseInt(value.substring(0, 2), 16) / 255.0; 112 | options.color = "#" + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4); 113 | } else if (key === 'width') { 114 | options.weight = value; 115 | } else if (key === 'Icon') { 116 | ioptions = _parse(e); 117 | if (ioptions.href) { options.href = ioptions.href; } 118 | } else if (key === 'href') { 119 | options.href = value; 120 | } 121 | } 122 | } 123 | return options; 124 | } 125 | 126 | for (var i = 0; i < sl.length; i++) { 127 | var e = sl[i], el; 128 | var options = {}, poptions = {}, ioptions = {}; 129 | el = e.getElementsByTagName("LineStyle"); 130 | if (el && el[0]) { options = _parse(el[0]); } 131 | el = e.getElementsByTagName("PolyStyle"); 132 | if (el && el[0]) { poptions = _parse(el[0]); } 133 | if (poptions.color) { options.fillColor = poptions.color; } 134 | if (poptions.opacity) { options.fillOpacity = poptions.opacity; } 135 | el = e.getElementsByTagName("IconStyle"); 136 | if (el && el[0]) { ioptions = _parse(el[0]); } 137 | if (ioptions.href) { 138 | // save anchor info until the image is loaded 139 | options.icon = new L.KMLIcon({ 140 | iconUrl: ioptions.href, 141 | shadowUrl: null, 142 | iconAnchorRef: {x: ioptions.x, y: ioptions.y}, 143 | iconAnchorType: {x: ioptions.xunits, y: ioptions.yunits} 144 | }); 145 | } 146 | style['#' + e.getAttribute('id')] = options; 147 | } 148 | return style; 149 | }, 150 | 151 | parseStyleMap: function (xml, existingStyles) { 152 | var sl = xml.getElementsByTagName("StyleMap"); 153 | 154 | for (var i = 0; i < sl.length; i++) { 155 | var e = sl[i], el; 156 | var smKey, smStyleUrl; 157 | 158 | el = e.getElementsByTagName("key"); 159 | if (el && el[0]) { smKey = el[0].textContent; } 160 | el = e.getElementsByTagName("styleUrl"); 161 | if (el && el[0]) { smStyleUrl = el[0].textContent; } 162 | 163 | if (smKey=='normal') 164 | { 165 | existingStyles['#' + e.getAttribute('id')] = existingStyles[smStyleUrl]; 166 | } 167 | } 168 | 169 | return; 170 | }, 171 | 172 | parseFolder: function (xml, style) { 173 | var el, layers = [], l; 174 | el = xml.getElementsByTagName('Folder'); 175 | for (var i = 0; i < el.length; i++) { 176 | if (!this._check_folder(el[i], xml)) { continue; } 177 | l = this.parseFolder(el[i], style); 178 | if (l) { layers.push(l); } 179 | } 180 | el = xml.getElementsByTagName('Placemark'); 181 | for (var j = 0; j < el.length; j++) { 182 | if (!this._check_folder(el[j], xml)) { continue; } 183 | l = this.parsePlacemark(el[j], xml, style); 184 | if (l) { layers.push(l); } 185 | } 186 | if (!layers.length) { return; } 187 | if (layers.length === 1) { return layers[0]; } 188 | return new L.FeatureGroup(layers); 189 | }, 190 | 191 | parsePlacemark: function (place, xml, style) { 192 | var i, j, el, options = {}; 193 | el = place.getElementsByTagName('styleUrl'); 194 | for (i = 0; i < el.length; i++) { 195 | var url = el[i].childNodes[0].nodeValue; 196 | for (var a in style[url]) 197 | { 198 | // for jshint 199 | if (true) 200 | { 201 | options[a] = style[url][a]; 202 | } 203 | } 204 | } 205 | var layers = []; 206 | 207 | var parse = ['LineString', 'Polygon', 'Point']; 208 | for (j in parse) { 209 | // for jshint 210 | if (true) 211 | { 212 | var tag = parse[j]; 213 | el = place.getElementsByTagName(tag); 214 | for (i = 0; i < el.length; i++) { 215 | var l = this["parse" + tag](el[i], xml, options); 216 | if (l) { layers.push(l); } 217 | } 218 | } 219 | } 220 | 221 | if (!layers.length) { 222 | return; 223 | } 224 | var layer = layers[0]; 225 | if (layers.length > 1) { 226 | layer = new L.FeatureGroup(layers); 227 | } 228 | 229 | var name, descr = ""; 230 | el = place.getElementsByTagName('name'); 231 | if (el.length && el[0].childNodes.length) { 232 | name = el[0].childNodes[0].nodeValue; 233 | } 234 | el = place.getElementsByTagName('description'); 235 | for (i = 0; i < el.length; i++) { 236 | for (j = 0; j < el[i].childNodes.length; j++) { 237 | descr = descr + el[i].childNodes[j].nodeValue; 238 | } 239 | } 240 | 241 | if (name) { 242 | layer.bindPopup("Example:
OPenDAP URL: http://test.opendap.org/dap/data/nc/sst.mnmean.nc.gz
Supported formats: Shapefile, GeoTIFF, GeoJSON, netCDF and HDF files.
Example:
OPeNDAP URL: http://test.opendap.org/dap/data/nc/sst.mnmean.nc.gz
Variable: sst